313 lines
12 KiB
PHP
313 lines
12 KiB
PHP
<?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;
|
|
}
|
|
}
|