feat: Implement DNS management with dedicated models, repositories, requests, controllers, and services, while refactoring authentication by removing Passport and Sanctum.
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
<?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 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 {
|
||||
Cache::forget("domain.{$domain->id}");
|
||||
Cache::forget("domain.{$domain->domain_name}");
|
||||
Cache::forget('domains.all');
|
||||
Cache::forget('domains.filtered');
|
||||
|
||||
if ($domain->users) {
|
||||
foreach ($domain->users as $user) {
|
||||
Cache::forget("user.{$user->id}.domains");
|
||||
}
|
||||
}
|
||||
|
||||
if ($domain->dns_manager_server_id) {
|
||||
Cache::forget("server.{$domain->dns_manager_server_id}.domains");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::warning('Failed to clear domain caches: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user