Add stubs for various Laravel components and scaffolding

- Created stubs for JavaScript and SASS assets.
- Added stubs for channel, command, component, controller, event, factory, job, listener, mail, middleware, migration, model, notification, observer, policy, request, resource, route provider, seeder, and validation rule.
- Implemented scaffolding for configuration, service provider, and Vite integration.
- Included example views for module structure.
- Introduced a module loader for Vite to handle asset paths dynamically.
This commit is contained in:
baodev0
2026-05-29 09:28:08 +07:00
parent fccb0c353a
commit 6bb4a47bfb
89 changed files with 3355 additions and 4560 deletions
@@ -124,6 +124,8 @@ class InvoiceTestController extends Controller
'companyAddress' => $settingValue->address ?? '',
'companyPhone' => $settingValue->phone ?? '',
'companyEmail' => $settingValue->email ?? '',
])->stream($invoice->invoice_number . '.pdf');
])
->setPaper('a4', 'portrait')
->stream($invoice->invoice_number . '.pdf');
}
}
}
@@ -11,6 +11,7 @@ use App\Support\Cache\CacheKey;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class SettingController extends Controller
@@ -99,4 +100,19 @@ class SettingController extends Controller
'message' => 'Cập nhật cài đặt thành công.',
]);
}
public function uploadMedia(Request $request): JsonResponse
{
$request->validate([
'file' => 'required|file|mimes:jpg,jpeg,png,webp,svg|max:5120',
]);
$path = $request->file('file')->store('system-config', 'public');
return response()->json([
'error' => false,
'url' => Storage::disk('public')->url($path),
'path' => $path,
]);
}
}
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api\Admin\Transaction;
use App\Enums\TransactionStatus;
use App\Http\Controllers\Controller;
use App\Mail\Customer\ManualDepositStatus;
use App\Models\Notification;
use App\Models\Log;
use App\Models\Transaction;
@@ -11,6 +12,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log as FacadesLog;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
class AdminTransactionController extends Controller
@@ -126,6 +128,28 @@ class AdminTransactionController extends Controller
]);
DB::commit();
try {
Mail::to($customer->email)->send(new ManualDepositStatus([
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_name' => $customer->fullname,
'transaction_code' => $transaction->public_code,
'amount' => $transaction->amount,
'status_label' => 'Đã duyệt',
'status_color' => '#15803d',
'status_bg' => '#f0fdf4',
'subject' => 'Yêu cầu nạp tiền đã được duyệt - ' . $transaction->public_code,
'status_message' => 'Yêu cầu nạp tiền của bạn đã được duyệt. Số tiền đã được cộng vào tài khoản và có thể sử dụng ngay.',
'deposit_date' => $transaction->created_at?->format('d/m/Y H:i:s') ?? now()->format('d/m/Y H:i:s'),
'processed_date' => now()->format('d/m/Y H:i:s'),
]));
} catch (\Throwable $e) {
FacadesLog::error('Không thể gửi email duyệt nạp tiền thủ công: ' . $e->getMessage(), [
'transaction_code' => $transaction->public_code,
'customer_email' => $customer->email,
]);
}
} catch (\Exception $e) {
DB::rollBack();
FacadesLog::error('AdminTransactionController::approve error: ' . $e->getMessage());
@@ -172,6 +196,28 @@ class AdminTransactionController extends Controller
]);
DB::commit();
try {
Mail::to($customer->email)->send(new ManualDepositStatus([
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_name' => $customer->fullname,
'transaction_code' => $transaction->public_code,
'amount' => $transaction->amount,
'status_label' => 'Không phù hợp',
'status_color' => '#b91c1c',
'status_bg' => '#fef2f2',
'subject' => 'Yêu cầu nạp tiền không phù hợp - ' . $transaction->public_code,
'status_message' => 'Yêu cầu nạp tiền của bạn chưa phù hợp để được duyệt. Vui lòng kiểm tra lại chứng từ hoặc liên hệ bộ phận hỗ trợ để được hướng dẫn thêm.',
'deposit_date' => $transaction->created_at?->format('d/m/Y H:i:s') ?? now()->format('d/m/Y H:i:s'),
'processed_date' => now()->format('d/m/Y H:i:s'),
]));
} catch (\Throwable $e) {
FacadesLog::error('Không thể gửi email từ chối nạp tiền thủ công: ' . $e->getMessage(), [
'transaction_code' => $transaction->public_code,
'customer_email' => $customer->email,
]);
}
} catch (\Exception $e) {
DB::rollBack();
FacadesLog::error('AdminTransactionController::reject error: ' . $e->getMessage());
@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Api\Service;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Api\Service\Concerns\ResolvesVm;
use App\Http\Services\vCenter;
use App\Models\ModuleVmware;
use App\Services\ActivityLogger;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -19,20 +18,18 @@ class VmRebuildController extends Controller
public function options(Request $request): JsonResponse
{
$productId = (int) $request->query('product');
$productId = $request->query('product');
if (!$productId) {
return response()->json(['error' => true, 'message' => 'Thiếu product id'], 422);
}
$vm = ModuleVmware::with(['order.orderItems.product.osVersions.osGroup'])
->find($productId);
if (!$vm) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404);
}
if ((int) $vm->customer_id !== (int) $request->user()->id) {
return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403);
$vm = $this->resolveVmById($productId, $request);
if ($vm instanceof JsonResponse) {
return $vm;
}
$vm->loadMissing(['order.orderItems.product.osVersions.osGroup']);
$product = optional($vm->order?->orderItems?->first())->product;
if (!$product) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy product của dịch vụ hiện tại'], 404);
@@ -63,19 +60,17 @@ class VmRebuildController extends Controller
{
$customer = $request->user();
$payload = $request->validate([
'product' => ['required', 'integer'],
'product' => ['required'],
'os_id' => ['required', 'integer', 'exists:os,id'],
]);
$vm = ModuleVmware::with(['order.orderItems.product', 'vCenter', 'ipAddress.host.datacenter.vCenter'])
->find($payload['product']);
if (!$vm) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404);
}
if ((int) $vm->customer_id !== (int) $customer->id) {
return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403);
$vm = $this->resolveVmById($payload['product'], $request);
if ($vm instanceof JsonResponse) {
return $vm;
}
$vm->loadMissing(['order.orderItems.product', 'vCenter', 'ipAddress.host.datacenter.vCenter']);
$product = optional($vm->order?->orderItems?->first())->product;
if (!$product) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy product của dịch vụ hiện tại'], 404);
@@ -123,20 +118,18 @@ class VmRebuildController extends Controller
public function addonOptions(Request $request): JsonResponse
{
$productId = (int) $request->query('product');
$productId = $request->query('product');
if (!$productId) {
return response()->json(['error' => true, 'message' => 'Thiếu product id'], 422);
}
$vm = ModuleVmware::with(['order.orderItems.product.addons'])
->find($productId);
if (!$vm) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404);
}
if ((int) $vm->customer_id !== (int) $request->user()->id) {
return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403);
$vm = $this->resolveVmById($productId, $request);
if ($vm instanceof JsonResponse) {
return $vm;
}
$vm->loadMissing(['order.orderItems.product.addons']);
$product = optional($vm->order?->orderItems?->first())->product;
if (!$product) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy product của dịch vụ hiện tại'], 404);
@@ -145,18 +138,23 @@ class VmRebuildController extends Controller
$addons = $product->addons()->where('status', true)->get()->map(function ($addon) {
return [
'id' => $addon->id,
'type' => $addon->type instanceof \BackedEnum ? $addon->type->value : (string) $addon->type,
'code' => strtolower((string) $addon->code),
'name' => $addon->name,
'price' => (float) $addon->price,
'min' => (int) ($addon->min ?? 0),
'max' => (int) ($addon->max ?? 0),
'step' => (int) ($addon->step ?? 1),
'prefix' => $addon->prefix,
'input_type' => $addon->input_type ?? 'number',
'sort_order' => (int) ($addon->sort_order ?? 0),
];
});
return response()->json([
'error' => false,
'data' => [
'data' => $addons->values(),
'meta' => [
'product_id' => $product->id,
'product_name' => $product->name,
'base_specs' => [
@@ -166,7 +164,6 @@ class VmRebuildController extends Controller
'bandwidth' => (int) ($product->bandwidth ?? 0),
'gpu' => $product->gpu,
],
'addons' => $addons->values(),
],
]);
}
@@ -175,23 +172,21 @@ class VmRebuildController extends Controller
{
$customer = $request->user();
$payload = $request->validate([
'product' => ['required', 'integer'],
'product' => ['required'],
'cpu' => ['nullable', 'integer', 'min:0'],
'ram' => ['nullable', 'integer', 'min:0'],
'disk' => ['nullable', 'integer', 'min:0'],
'bandwidth' => ['nullable', 'integer', 'min:0'],
'gpu' => ['nullable', 'string', 'max:255'],
'gpu' => ['nullable'],
]);
$vm = ModuleVmware::with(['vCenter', 'ipAddress.host.datacenter.vCenter'])
->find($payload['product']);
if (!$vm) {
return response()->json(['error' => true, 'message' => 'Không tìm thấy VM'], 404);
}
if ((int) $vm->customer_id !== (int) $customer->id) {
return response()->json(['error' => true, 'message' => 'Bạn không có quyền thao tác VM này'], 403);
$vm = $this->resolveVmById($payload['product'], $request);
if ($vm instanceof JsonResponse) {
return $vm;
}
$vm->loadMissing(['vCenter', 'ipAddress.host.datacenter.vCenter']);
$vcenter = $vm->vCenter ?? $vm->ipAddress?->host?->datacenter?->vCenter;
if (!$vcenter || !$serviceVCenter->loginServer($vcenter)) {
return response()->json(['error' => true, 'message' => 'Không thể đăng nhập vCenter'], 400);
@@ -235,4 +230,4 @@ class VmRebuildController extends Controller
],
]);
}
}
}
@@ -6,12 +6,16 @@ use App\Enums\TransactionStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\DepositRequest;
use App\Http\Services\Telegram;
use App\Mail\Admin\ManualDepositPendingNotification;
use App\Mail\Customer\ManualDepositStatus;
use App\Models\Log;
use App\Models\Setting;
use App\Models\Transaction;
use App\Services\ActivityLogger;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
@@ -196,6 +200,7 @@ class ManualDepositController extends Controller
try {
(new Telegram())->SendManualDepositPendingApproval($user, $transaction);
$this->sendManualDepositAdminEmail($user, $transaction, $request);
} catch (\Exception) {
// Không để lỗi Telegram ảnh hưởng response
}
@@ -214,6 +219,27 @@ class ManualDepositController extends Controller
newValues: ['public_code' => $transaction->public_code, 'amount' => $transaction->amount, 'has_proof' => true],
);
try {
Mail::to($user->email)->send(new ManualDepositStatus([
'customer_id' => $user->id,
'customer_email' => $user->email,
'customer_name' => $user->fullname,
'transaction_code' => $transaction->public_code,
'amount' => $transaction->amount,
'status_label' => 'Đang chờ duyệt',
'status_color' => '#f16723',
'status_bg' => '#fff7ed',
'subject' => 'Yêu cầu nạp tiền đang chờ duyệt - ' . $transaction->public_code,
'status_message' => 'Yêu cầu nạp tiền của bạn đã được ghi nhận. Chúng tôi sẽ kiểm tra chứng từ và phản hồi kết quả trong thời gian sớm nhất.',
'deposit_date' => $transaction->created_at?->format('d/m/Y H:i:s') ?? now()->format('d/m/Y H:i:s'),
]));
} catch (\Throwable $e) {
\Log::error('Không thể gửi email trạng thái nạp tiền thủ công: ' . $e->getMessage(), [
'transaction_code' => $transaction->public_code,
'customer_email' => $user->email,
]);
}
return response()->json([
'error' => false,
'message' => 'Yêu cầu nạp tiền đã được ghi nhận, vui lòng chờ admin xác nhận',
@@ -239,4 +265,37 @@ class ManualDepositController extends Controller
'path' => $path,
]);
}
private function sendManualDepositAdminEmail($customer, Transaction $transaction, Request $request): void
{
try {
$setting = Setting::where('key', 'setting')->first();
$settingValue = $setting ? json_decode((string) $setting->value, true) : [];
$adminEmail = $settingValue['admin_email'] ?? null;
if (empty($adminEmail)) {
\Log::warning('Manual deposit admin email not sent: admin_email not configured.', [
'transaction_code' => $transaction->public_code,
]);
return;
}
Mail::to($adminEmail)->send(new ManualDepositPendingNotification([
'company_name' => $settingValue['company'] ?? config('app.name', 'Portal Admin'),
'customer_name' => $customer->fullname ?: trim(($customer->firstname ?? '') . ' ' . ($customer->lastname ?? '')),
'customer_email' => $customer->email,
'customer_phone' => $customer->phone ?? null,
'client_ip' => $request->ip(),
'transaction_code' => $transaction->public_code,
'amount' => $transaction->amount,
'proof_image_url' => $transaction->proof_image ? Storage::disk('public')->url($transaction->proof_image) : null,
'created_at' => now()->format('d/m/Y H:i:s'),
]));
} catch (\Throwable $e) {
\Log::error('Không thể gửi email admin thông báo nạp tiền chờ duyệt: ' . $e->getMessage(), [
'transaction_code' => $transaction->public_code,
'customer_email' => $customer->email ?? null,
]);
}
}
}
@@ -1,378 +0,0 @@
<?php
namespace App\Http\Controllers\Backend;
use App\Http\Controllers\Controller;
use App\Http\Requests\Domain\DomainRemoveRequest;
use App\Http\Requests\Domain\DomainRequest;
use App\Repositories\DnsManager\Domain\DnsDomainRepositoryInterface;
use App\Services\ServerService;
use Exception;
use Illuminate\Support\Carbon;
use App\Support\Cache\CacheKey;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class DomainController extends Controller
{
public function __construct(
public DnsDomainRepositoryInterface $domainRepository,
public ServerService $serverService
) {}
public function index()
{
$title = 'Domains';
return view('Backend.domains.index', compact('title'));
}
public function getAll()
{
$domains = $this->domainRepository->filter([], ['users', 'server'])->map(function ($domain) {
return [
'id' => $domain->id,
'name' => $domain->domain_name,
'server' => $domain->server ? $domain->server->ip_address : '',
'user' => $domain->users->pluck('name')->implode(', '),
'checkbox' => '<input class="form-check-input m-0 align-middle" value="' . $domain->id . '" type="checkbox" aria-label="Select tag">',
'created_at' => Carbon::parse($domain->created_at)->format('Y-m-d H:i:s'),
'action' => $this->domainActionButtons($domain),
];
});
return response()->json(['data' => $domains]);
}
public function create()
{
$title = 'Add Domain';
return view('Backend.domains.create', compact('title'));
}
public function store(DomainRequest $request)
{
$validated = $request->validated();
$isCreated = $this->domainRepository->findDomain($validated['domain_name']);
if (!empty($isCreated)) {
return response()->json([
'success' => false,
'message' => "Domain '{$validated['domain_name']}' đã tồn tại trong hệ thống!",
]);
}
DB::beginTransaction();
try {
$userIds = $validated['user_id'] ?? [];
$domainData = collect($validated)->except('user_id')->toArray();
$domain = $this->domainRepository->create($domainData);
$domain->users()->attach($userIds);
$domain->save();
try {
$server = $this->serverService->findServerByID($domain->dns_manager_server_id);
if (!$server) {
throw new Exception("Không tìm thấy server với ID: {$domain->dns_manager_server_id}");
}
$existingDomainInfo = $this->serverService->getDomainInfo($domain->domain_name);
if ($existingDomainInfo) {
$this->domainRepository->update($domain->id, [
'is_created' => 1,
'plesk_id' => $existingDomainInfo['id'],
]);
} else {
$response = $this->serverService->createDomain($domain->toArray());
if (!$response || !isset($response['id'])) {
throw new Exception('Không thể tạo domain trên server. Vui lòng kiểm tra lại thông tin server.');
}
$this->domainRepository->update($domain->id, [
'is_created' => 1,
'plesk_id' => $response['id'],
]);
}
} catch (Exception $domainError) {
Log::error('Lỗi khi tạo domain: ' . $domainError->getMessage());
}
DB::commit();
$domain = $domain->refresh();
$message = $domain->is_created == 1 && $domain->plesk_id
? "Domain '{$domain->domain_name}' đã được xử lý thành công trên server!"
: "Domain '{$domain->domain_name}' đã được lưu vào database nhưng chưa thể xử lý trên server.";
return response()->json(['success' => true, 'message' => $message, 'url' => route('admin.domain.index')]);
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => 'Có lỗi xảy ra: ' . $error->getMessage()]);
}
}
public function edit(int $id)
{
$domain = $this->domainRepository->find($id);
if (empty($domain)) {
return back()->withErrors("Không tìm thấy domain với ID: {$id}");
}
$title = 'Edit domain';
return view('Backend.domains.edit', compact('title', 'domain'));
}
public function update(DomainRequest $request, int $id)
{
$domain = $this->domainRepository->find($id);
if (empty($domain)) {
return response()->json(['success' => false, 'message' => "Không tìm thấy domain với ID: {$id}"]);
}
$validated = $request->validated();
DB::beginTransaction();
try {
$userIds = $validated['user_id'] ?? [];
$domainData = collect($validated)->except('user_id')->toArray();
$this->domainRepository->update($id, $domainData);
$domain->users()->sync($userIds);
try {
$updatedDomain = $this->domainRepository->find($id);
$server = $this->serverService->findServerByID($updatedDomain->dns_manager_server_id);
if (!$server) {
throw new Exception("Không tìm thấy server với ID: {$updatedDomain->dns_manager_server_id}");
}
$existingDomainInfo = $this->serverService->getDomainInfo($updatedDomain->domain_name);
if ($existingDomainInfo) {
$this->serverService->updateDomain($existingDomainInfo['id'], $updatedDomain->toArray());
$this->domainRepository->update($updatedDomain->id, [
'is_created' => 1,
'plesk_id' => $existingDomainInfo['id'],
]);
} else {
$response = $this->serverService->createDomain($updatedDomain->toArray());
if (!$response || !isset($response['id'])) {
throw new Exception('Không thể tạo domain trên server.');
}
$this->domainRepository->update($updatedDomain->id, [
'is_created' => 1,
'plesk_id' => $response['id'],
]);
}
} catch (Exception $domainError) {
Log::error('Lỗi khi cập nhật domain: ' . $domainError->getMessage());
}
DB::commit();
$updatedDomain = $this->domainRepository->find($id);
$message = $updatedDomain->is_created == 1 && $updatedDomain->plesk_id
? "Domain '{$updatedDomain->domain_name}' đã được cập nhật thành công trên server!"
: "Domain '{$updatedDomain->domain_name}' đã được cập nhật trong database nhưng chưa thể xử lý trên server.";
return response()->json(['success' => true, 'message' => $message, 'url' => route('admin.domain.index')]);
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => 'Có lỗi xảy ra: ' . $error->getMessage()]);
}
}
public function record(int $id = 0)
{
$domain = $this->domainRepository->findWithRelations($id, ['record']);
if (empty($domain)) {
return back()->withErrors("Không tìm thấy domain với ID: {$id}");
}
$title = strtoupper($domain->domain_name) . ' Records';
return view('Backend.domains.view', compact('domain', 'title', 'id'));
}
public function destroy(int $id)
{
$domain = $this->domainRepository->find($id);
if (!$domain) {
return response()->json(['success' => false, 'message' => "Không tìm thấy domain với ID: {$id}"]);
}
try {
if ($domain->is_created !== 1 || !$domain->plesk_id) {
$this->domainRepository->delete($domain->id);
return response()->json([
'success' => true,
'message' => "Domain '{$domain->domain_name}' đã được xóa khỏi database.",
'url' => route('admin.domain.index'),
]);
}
$server = $this->serverService->findServerByID($domain->dns_manager_server_id);
if (!$server) {
return response()->json(['success' => false, 'message' => "Không tìm thấy server với ID: {$domain->dns_manager_server_id}"]);
}
$removed = $this->serverService->removeDomain($domain->plesk_id);
if (!$removed) {
return response()->json(['success' => false, 'message' => "Không thể xóa domain '{$domain->domain_name}' trên server."]);
}
$this->domainRepository->delete($domain->id);
$this->clearDomainCaches($domain);
return response()->json([
'success' => true,
'message' => "Domain '{$domain->domain_name}' đã được xóa thành công khỏi server và database!",
'url' => route('admin.domain.index'),
]);
} catch (Exception $error) {
return response()->json(['success' => false, 'message' => 'Có lỗi xảy ra khi xóa domain: ' . $error->getMessage()]);
}
}
public function destroyCustom(DomainRemoveRequest $request)
{
$request->validated();
$domains = $this->domainRepository->findWhereIn('id', $request->get('ids'));
if (!$domains || $domains->isEmpty()) {
return response()->json(['success' => false, 'message' => 'Không tìm thấy domain nào.']);
}
$successCount = 0;
$errorCount = 0;
$errors = [];
foreach ($domains as $domain) {
try {
if ($domain->is_created !== 1 || !$domain->plesk_id) {
$this->domainRepository->delete($domain->id);
$successCount++;
continue;
}
$server = $this->serverService->findServerByID($domain->dns_manager_server_id);
if (!$server) {
$errors[] = "Domain '{$domain->domain_name}': Không tìm thấy server";
$errorCount++;
continue;
}
$removed = $this->serverService->removeDomain($domain->plesk_id);
if (!$removed) {
$errors[] = "Domain '{$domain->domain_name}': Không thể xóa trên server";
$errorCount++;
continue;
}
$this->domainRepository->delete($domain->id);
$this->clearDomainCaches($domain);
$successCount++;
} catch (Exception $error) {
$errors[] = "Domain '{$domain->domain_name}': " . $error->getMessage();
$errorCount++;
}
}
if ($successCount > 0 && $errorCount === 0) {
$message = "Đã xóa thành công {$successCount} domain!";
} elseif ($successCount > 0) {
$message = "Đã xóa thành công {$successCount} domain, {$errorCount} domain gặp lỗi.";
} else {
$message = 'Không thể xóa domain nào. Vui lòng kiểm tra lại.';
}
return response()->json([
'success' => $errorCount === 0,
'message' => $message,
'details' => ['success_count' => $successCount, 'error_count' => $errorCount, 'errors' => $errors],
'url' => route('admin.domain.index'),
]);
}
private function domainActionButtons($domain): string
{
$editUrl = route('admin.domain.edit', ['id' => $domain->id]);
$recordUrl = route('admin.domain.record', ['id' => $domain->id]);
$deleteUrl = route('admin.domain.destroy', ['id' => $domain->id]);
return <<<HTML
<a class="btn btn-sm btn-icon btn-primary" href="{$editUrl}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"/>
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"/>
<path d="M16 5l3 3"/>
</svg>
<span class="sr-only">Edit</span>
</a>
<a class="btn btn-sm btn-icon btn-success" href="{$recordUrl}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M9 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2"/>
<path d="M9 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"/>
<path d="M9 14h.01"/><path d="M9 17h.01"/><path d="M12 16l1 1l3 -3"/>
</svg>
<span class="sr-only">Records</span>
</a>
<a class="btn btn-sm btn-icon btn-icon__remove btn-danger"
href="{$deleteUrl}"
data-dt-single-action=""
data-method="DELETE"
data-confirmation-modal="true"
data-bs-target="#modal-remove-tags"
data-bs-toggle="modal"
data-confirmation-modal-title="Confirm delete"
data-confirmation-modal-message="Do you really want to delete this record?"
data-confirmation-modal-button="Delete"
data-confirmation-modal-cancel-button="Cancel">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M4 7l16 0"/><path d="M10 11l0 6"/><path d="M14 11l0 6"/>
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/>
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/>
</svg>
<span class="sr-only">Delete</span>
</a>
HTML;
}
private function clearDomainCaches($domain): void
{
try {
// Clear specific domain keys
Cache::forget(CacheKey::build('domain', 'detail', ['id' => $domain->id]));
Cache::forget(CacheKey::build('domain', 'detail', ['name' => $domain->domain_name]));
Cache::forget(CacheKey::build('domain', 'all'));
if ($domain->users) {
foreach ($domain->users as $user) {
Cache::forget(CacheKey::build('domain', 'user-list', ['user_id' => $user->id]));
}
}
if ($domain->dns_manager_server_id) {
Cache::forget(CacheKey::build('domain', 'server-list', ['server_id' => $domain->dns_manager_server_id]));
}
} catch (Exception $e) {
Log::warning('Failed to clear domain caches: ' . $e->getMessage());
}
}
}
@@ -1,312 +0,0 @@
<?php
namespace App\Http\Controllers\Backend;
use App\Http\Controllers\Controller;
use App\Http\Requests\Record\RecordRemoveRequest;
use App\Repositories\DnsManager\Domain\DnsDomainRepositoryInterface;
use App\Repositories\DnsManager\Record\DnsRecordRepositoryInterface;
use App\Services\ServerService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class RecordController extends Controller
{
protected array $rules = [
'A' => [
'name' => 'required',
'type' => 'required',
'ttl' => 'required',
'value' => 'required|ip|ipv4',
'plesk_id' => 'nullable',
],
'AAAA' => [
'name' => 'required',
'type' => 'required',
'ttl' => 'required',
'value' => 'required|ip|ipv6',
'plesk_id' => 'nullable',
],
'CNAME' => [
'name' => 'required',
'type' => 'required',
'ttl' => 'required',
'value' => 'required',
'plesk_id' => 'nullable',
],
'MX' => [
'name' => 'required',
'type' => 'required',
'ttl' => 'required',
'value' => 'required',
'priority' => 'required',
'plesk_id' => 'nullable',
],
'TXT' => [
'name' => 'required',
'type' => 'required',
'ttl' => 'required',
'value' => 'required',
'plesk_id' => 'nullable',
],
'CAA' => [
'name' => 'required',
'type' => 'required',
'ttl' => 'required',
'value' => 'required',
'plesk_id' => 'nullable',
],
'SRV' => [
'type' => 'required',
'ttl' => 'required',
'value' => 'required',
'service_name' => 'required',
'protocol' => 'required',
'weight' => 'required',
'port' => 'required',
'priority' => 'required',
'plesk_id' => 'nullable',
],
];
public function __construct(
public DnsDomainRepositoryInterface $domainRepository,
public DnsRecordRepositoryInterface $recordRepository,
public ServerService $serverService
) {}
public function index()
{
$title = 'All Records';
return view('Backend.records.index', compact('title'));
}
public function getAll()
{
$records = $this->recordRepository->filter([], ['domain'])->map(function ($record) {
return [
'id' => $record->id,
'name' => Str::limit($record->name, 20, '...'),
'type' => $record->type,
'value' => Str::limit($record->value, 20, '...'),
'domain' => $record->domain ? $record->domain->domain_name : '',
'checkbox' => '<input class="form-check-input m-0 align-middle" value="' . $record->id . '" type="checkbox" aria-label="Select tag">',
'created_at' => Carbon::parse($record->created_at)->format('Y-m-d H:i:s'),
'action' => $this->recordActionButtons($record),
];
});
return response()->json(['data' => $records]);
}
public function create(int $id)
{
$title = 'Add Records';
return view('Backend.records.create', compact('title', 'id'));
}
public function store(Request $request, int $id = 0)
{
$domain = $this->domainRepository->find($id);
if (empty($domain)) {
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
}
$validated = Validator::make($request->all(), $this->rules[$request->get('type')] ?? []);
if ($validated->fails()) {
return response()->json(['success' => false, 'message' => $validated->errors()->first()]);
}
$request->merge(['dns_manager_domain_id' => $id, 'domain' => $domain->domain_name]);
if (empty($request->get('plesk_id'))) {
$this->serverService->findServerByID($domain->dns_manager_server_id);
$this->serverService->handlePayload($request->all());
$record = $this->serverService->addRecord();
if (!empty($record) && $record['error']) {
return response()->json(['success' => false, 'message' => $record['message'] ?? 'Failed to add record on server.']);
}
}
DB::beginTransaction();
try {
if (isset($record)) {
$request->merge(['plesk_id' => $record['data']['id'] ?? 0]);
}
$this->recordRepository->create($request->all());
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => $error->getMessage()]);
}
return response()->json([
'success' => true,
'message' => 'Add record successfully',
'url' => route('admin.domain.record', ['id' => $id]),
]);
}
public function edit(int $id = 0, int $record_id = 0)
{
$domain = $this->domainRepository->find($id);
if (empty($domain)) {
return back()->withErrors('These credentials do not match our records.');
}
$record = $this->recordRepository->find($record_id);
if (empty($record)) {
return back()->withErrors('These credentials do not match our records.');
}
$title = 'Edit Record';
return view('Backend.records.edit', compact('title', 'record', 'id'));
}
public function update(Request $request, int $id = 0, int $record_id = 0)
{
$domain = $this->domainRepository->find($id);
if (empty($domain)) {
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
}
$record = $this->recordRepository->find($record_id);
if (empty($record)) {
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
}
$validated = Validator::make($request->all(), $this->rules[$request->get('type')] ?? []);
if ($validated->fails()) {
return response()->json(['success' => false, 'message' => $validated->errors()->first()]);
}
$this->serverService->findServerByID($domain->dns_manager_server_id);
$this->serverService->handlePayload($request->all());
$updatedRecord = $this->serverService->updateRecord($record->plesk_id);
if (!empty($updatedRecord) && $updatedRecord['error']) {
return response()->json(['success' => false, 'message' => $updatedRecord['message'] ?? 'Failed to update record on server.']);
}
DB::beginTransaction();
try {
$this->recordRepository->update($record_id, $request->all());
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => $error->getMessage()]);
}
return response()->json([
'success' => true,
'message' => 'Update record successfully',
'url' => route('admin.domain.record', ['id' => $id]),
]);
}
public function destroy(int $id = 0)
{
$record = $this->recordRepository->findWithRelations($id, ['domain']);
if (empty($record) || empty($record->domain)) {
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
}
$this->serverService->findServerByID($record->domain->dns_manager_server_id);
$record_delete = $this->serverService->deleteRecord($record->plesk_id);
if (!empty($record_delete) && $record_delete['error']) {
return response()->json(['success' => false, 'message' => $record_delete['message'] ?? 'Failed to delete record on server.']);
}
DB::beginTransaction();
try {
$domainId = $record->dns_manager_domain_id;
$this->recordRepository->delete($id);
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => $error->getMessage()]);
}
return response()->json([
'success' => true,
'message' => 'Deleted record successfully',
'url' => route('admin.domain.record', ['id' => $domainId]),
]);
}
public function destroyCustom(RecordRemoveRequest $request)
{
$request->validated();
$records = $this->recordRepository->findWhereIn('id', $request->get('ids'), ['domain']);
if (!$records) {
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
}
try {
foreach ($records->all() as $record) {
if (empty($record->domain)) continue;
$this->serverService->findServerByID($record->domain->dns_manager_server_id);
$this->serverService->deleteRecord($record->plesk_id);
$this->recordRepository->delete($record->id);
}
} catch (Exception $error) {
return response()->json(['success' => false, 'message' => $error->getMessage()]);
}
return response()->json([
'success' => true,
'message' => 'Deleted successfully!',
'url' => route('admin.record.index'),
]);
}
private function recordActionButtons($record): string
{
$domainId = $record->domain ? $record->domain->id : 0;
$editUrl = route('admin.record.edit', ['id' => $domainId, 'record_id' => $record->id]);
$deleteUrl = route('admin.record.destroy', ['id' => $record->id]);
return <<<HTML
<a class="btn btn-sm btn-icon btn-primary" href="{$editUrl}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"/>
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"/>
<path d="M16 5l3 3"/>
</svg>
<span class="sr-only">Edit</span>
</a>
<a class="btn btn-sm btn-icon btn-icon__remove btn-danger"
href="{$deleteUrl}"
data-dt-single-action=""
data-method="DELETE"
data-confirmation-modal="true"
data-bs-target="#modal-remove-tags"
data-bs-toggle="modal"
data-confirmation-modal-title="Confirm delete"
data-confirmation-modal-message="Do you really want to delete this record?"
data-confirmation-modal-button="Delete"
data-confirmation-modal-cancel-button="Cancel">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M4 7l16 0"/><path d="M10 11l0 6"/><path d="M14 11l0 6"/>
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/>
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/>
</svg>
<span class="sr-only">Delete</span>
</a>
HTML;
}
}
@@ -1,204 +0,0 @@
<?php
namespace App\Http\Controllers\Backend;
use App\Http\Controllers\Controller;
use App\Http\Requests\Server\ServerRemoveRequest;
use App\Http\Requests\Server\ServerRequest;
use App\Repositories\DnsManager\Server\DnsServerRepositoryInterface;
use App\Services\ServerService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
class ServerController extends Controller
{
public function __construct(
public DnsServerRepositoryInterface $serverRepository,
public ServerService $serverService
) {}
public function index()
{
$title = 'Server Hosting Manager';
return view('Backend.servers.index', compact('title'));
}
public function getAll()
{
$servers = $this->serverRepository->getAll()->map(function ($server) {
return [
'id' => $server->id,
'name' => $server->name,
'ip' => $server->ip_address,
'status' => $server->getStatus(),
'checkbox' => '<input class="form-check-input m-0 align-middle" value="' . $server->id . '" type="checkbox" aria-label="Select tag">',
'created_at' => Carbon::parse($server->created_at)->format('Y-m-d H:i:s'),
'action' => $this->serverActionButtons($server),
];
});
return response()->json(['data' => $servers]);
}
public function create()
{
$title = 'Add New Server Hosting';
return view('Backend.servers.create', compact('title'));
}
public function connect(ServerRequest $request)
{
$request->validated();
if (!$request->ajax()) {
return response()->json(['success' => false, 'message' => 'Method not support']);
}
$status = $this->serverService->checkConnection($request->all());
if ($status) {
return response()->json(['success' => true, 'message' => 'Connection established successfully.']);
}
return response()->json([
'success' => false,
'message' => 'Connection attempt failed. Please check your credentials or server settings.',
]);
}
public function store(ServerRequest $request)
{
$request->validated();
DB::beginTransaction();
try {
$data = $request->all();
$data['password'] = Crypt::encryptString($request->password);
$this->serverRepository->create($data);
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => $error->getMessage()]);
}
return response()->json([
'success' => true,
'message' => 'Created successfully!',
'url' => route('admin.server.index'),
]);
}
public function edit(int $id)
{
$server = $this->serverRepository->find($id);
if (!$server) {
return back()->withErrors('Invalid Request');
}
$title = 'Update Server Hosting';
return view('Backend.servers.edit', compact('title', 'server'));
}
public function update(ServerRequest $request, int $id)
{
$request->validated();
DB::beginTransaction();
try {
$data = $request->all();
$data['password'] = Crypt::encryptString($request->password);
$this->serverRepository->update($id, $data);
DB::commit();
} catch (Exception $error) {
DB::rollBack();
return response()->json(['success' => false, 'message' => $error->getMessage()]);
}
return response()->json([
'success' => true,
'message' => 'Updated successfully!',
'url' => route('admin.server.index'),
]);
}
public function destroy(int $id)
{
$server = $this->serverRepository->find($id);
if (!$server) {
return response()->json(['success' => false, 'message' => 'Invalid Request']);
}
$this->serverRepository->delete($id);
return response()->json([
'success' => true,
'message' => 'Deleted successfully!',
'url' => route('admin.server.index'),
]);
}
public function destroyCustom(ServerRemoveRequest $request)
{
$request->validated();
$servers = $this->serverRepository->findWhereIn('id', $request->get('ids'));
if (!$servers) {
return response()->json(['success' => false, 'message' => 'Invalid Request']);
}
foreach ($servers->all() as $server) {
$this->serverRepository->delete($server->id);
}
return response()->json([
'success' => true,
'message' => 'Deleted successfully!',
'url' => route('admin.server.index'),
]);
}
private function serverActionButtons($server): string
{
$editUrl = route('admin.server.edit', ['id' => $server->id]);
$deleteUrl = route('admin.server.destroy', ['id' => $server->id]);
return <<<HTML
<a class="btn btn-sm btn-icon btn-primary" href="{$editUrl}">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path>
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"></path>
<path d="M16 5l3 3"></path>
</svg>
<span class="sr-only">Edit</span>
</a>
<a class="btn btn-sm btn-icon btn-icon__remove btn-danger"
href="{$deleteUrl}"
data-dt-single-action=""
data-method="DELETE"
data-confirmation-modal="true"
data-bs-target="#modal-remove-tags"
data-bs-toggle="modal"
data-confirmation-modal-title="Confirm delete"
data-confirmation-modal-message="Do you really want to delete this record?"
data-confirmation-modal-button="Delete"
data-confirmation-modal-cancel-button="Cancel">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M4 7l16 0"></path>
<path d="M10 11l0 6"></path>
<path d="M14 11l0 6"></path>
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path>
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path>
</svg>
<span class="sr-only">Delete</span>
</a>
HTML;
}
}
@@ -1,256 +0,0 @@
<?php
namespace App\Http\Controllers\rest;
use App\Http\Controllers\Controller;
use App\Http\Services\vCenter;
use App\Repositories\Module\Datacenter\DatacenterRepositoryInterface;
use App\Repositories\Module\Datastore\DatastoreRepositoryInterface;
use App\Repositories\Module\Host\HostRepositoryInterface;
use App\Repositories\Module\IpAddress\IpAddressRepositoryInterface;
use App\Repositories\Module\Network\NetworkRepositoryInterface;
use App\Repositories\OsGroup\OsGroupRepositoryInterface;
use App\Repositories\vCenter\vCenterRepositoryInterface;
use Illuminate\Http\Request;
class ModuleController extends Controller
{
public function __construct(
public vCenterRepositoryInterface $vCenterRepository,
public DatacenterRepositoryInterface $datacenterRepository,
public HostRepositoryInterface $hostRepository,
public DatastoreRepositoryInterface $datastoreRepository,
public NetworkRepositoryInterface $networkRepository,
public IpAddressRepositoryInterface $ipAddressRepository,
public vCenter $vCenter,
public OsGroupRepositoryInterface $osGroupRepository
)
{
parent::__construct();
}
public function getVCenter()
{
return response()->json(
[
'error' => false,
'data' => $this->vCenterRepository->filter(['status' => 1])
]
);
}
public function getDatacenter(Request $request)
{
$vCenter_id = $request->get('vcenter');
if (!$vCenter_id) {
return response()->json(['error' => true, 'message' => 'Please choose vCenter']);
}
$vcenter = $this->vCenterRepository->find($vCenter_id);
if (!$vcenter) {
return response()->json(['error' => true, 'message' => 'Can\'t find vCenter']);
}
$datacenter = $this->datacenterRepository->filter(
[
'vcenter_id' => $vCenter_id
],
[],
[],
['id', 'name', 'datacenter_id']
);
if (count($datacenter) > 0) {
return response()->json(['error' => false, 'data' => $datacenter]);
}
return response()->json([
'error' => true,
'message' => 'Can\'t find Datacenter by vCenter ID #' . $vCenter_id
]);
}
public function getHost(Request $request)
{
$dataCenter_id = $request->get('datacenter');
if (!$dataCenter_id) {
return response()->json(['error' => true, 'message' => 'Please choose Datacenter']);
}
$datacenter = $this->datacenterRepository->find($dataCenter_id);
if (!$datacenter) {
return response()->json(['error' => true, 'message' => 'Can\'t find Datacenter']);
}
$host = $this->hostRepository->filter(
[
'module_datacenter_id' => $datacenter->id
],
[],
[],
['id', 'name']
);
if (count($host) > 0) {
return response()->json(['error' => false, 'data' => $host]);
}
return response()->json([
'error' => true,
'message' => 'Can\'t find Host by Datacenter ID #' . $dataCenter_id
]);
}
public function getDatastore(Request $request)
{
$host_id = $request->get('host');
if (!$host_id) {
return response()->json(['error' => true, 'message' => 'Please choose Host']);
}
$host = $this->hostRepository->find($host_id);
if (!$host) {
return response()->json(['error' => true, 'message' => 'Can\'t find Datacenter']);
}
$datastores = $this->datastoreRepository->filter(
[
'module_host_id' => $host_id
],
[],
[],
['id', 'name']
);
if (count($datastores) > 0) {
return response()->json(['error' => false, 'data' => $datastores]);
}
return response()->json([
'error' => true,
'message' => 'Can\'t find Datastore by Host ID #' . $host_id
]);
}
public function getNetwork(Request $request)
{
$host_id = $request->get('host');
if (!$host_id) {
return response()->json(['error' => true, 'message' => 'Please choose Host']);
}
$host = $this->hostRepository->find($host_id);
if (!$host) {
return response()->json(['error' => true, 'message' => 'Can\'t find Datacenter']);
}
$networks = $this->networkRepository->filter(
[
'module_host_id' => $host_id
],
[],
[],
['id', 'name']
);
if (count($networks) > 0) {
return response()->json(['error' => false, 'data' => $networks]);
}
return response()->json(['error' => true, 'message' => 'Can\'t find Network by Host ID #' . $host_id]);
}
public function getIpAddress(Request $request)
{
$network_id = $request->get('network');
if (!$network_id) {
return response()->json(['error' => true, 'message' => 'Please choose Network']);
}
$network = $this->networkRepository->find($network_id);
if (!$network) {
return response()->json(['error' => true, 'message' => 'Can\'t find Network']);
}
$ipAddress = $this->ipAddressRepository->filter(
[
'module_network_id' => $network_id
],
[],
[],
['id', 'ip']
);
if (count($ipAddress) > 0) {
return response()->json(
[
'error' => false,
'data' => $ipAddress->map(function ($item) {
$item['name'] = $item['ip'];
return $item;
})
]
);
}
return response()->json(['error' => true, 'message' => 'Can\'t find IP by Network ID #' . $network_id]);
}
public function getOsServerVersion(Request $request)
{
$host_id = $request->get('host');
if (!$host_id) {
return response()->json(['error' => true, 'message' => 'Please choose Host']);
}
$host = $this->hostRepository->findWithRelationships($host_id, ['datacenter.vCenter']);
if (!$host) {
return response()->json(['error' => true, 'message' => 'Can\'t find Datastore']);
}
$this->vCenter->token = $host->Datacenter->vCenter->token ?? '';
$this->vCenter->apiUri = $host->Datacenter->vCenter->host ?? '';
$listVersion = $this->vCenter->getAllVersion($host->template);
if ($listVersion === "Login_Again") {
$token = $this->vCenter->loginServer($host->datacenter->vCenter);
if ($token) {
$this->vCenterRepository->update($host->datacenter->vcenter_id, ['token' => $token]);
$this->vCenter->token = $token;
}
}
$listVersion = $this->vCenter->getAllVersion($host->template);
if ($listVersion) {
return response()->json(['error' => false, 'data' => $listVersion]);
}
return response()->json([
'error' => true,
'message' => 'Can\'t find Version OS by Host ID #' . $host_id
]);
}
public function getOsGroup(Request $request)
{
$host_id = $request->get('host');
if (!$host_id) {
return response()->json(['error' => true, 'message' => 'Please choose Host']);
}
$host = $this->hostRepository->find($host_id);
if (!$host) {
return response()->json(['error' => true, 'message' => 'Can\'t find Host']);
}
$groups = $this->osGroupRepository->filter(
[
'module_host_id' => $host_id
],
['host'], // Include host relationship
[],
['id', 'name', 'module_host_id'] // Add module_host_id to select
);
if (count($groups) > 0) {
return response()->json(['error' => false, 'data' => $groups]);
}
return response()->json([
'error' => true,
'message' => 'Can\'t find Os Group by Host ID #' . $host_id
]);
}
}