File: /home/xedaptot/be.naniguide.com/app/Http/Controllers/Refactor/Admin/SystemTemplateController.php
<?php
namespace App\Http\Controllers\Refactor\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Model\SystemTemplate;
class SystemTemplateController extends Controller
{
public function index(Request $request)
{
if (\Gate::denies('read', new SystemTemplate())) {
return $this->notAuthorized();
}
$stats = [
'total' => SystemTemplate::count(),
];
return view('refactor.pages.admin.system-pages.index', compact('stats'));
}
public function listing(Request $request)
{
if (\Gate::denies('read', new SystemTemplate())) {
return $this->notAuthorized();
}
$request->merge([
'sort_order' => $request->sort_order ?? 'system_templates.id',
'sort_direction' => $request->sort_direction ?? 'asc',
]);
$query = SystemTemplate::search($request);
if ($request->keyword) {
$keyword = $request->keyword;
$query->where(function ($q) use ($keyword) {
$q->where('system_templates.alias', 'like', '%' . $keyword . '%')
->orWhereHas('template', function ($tq) use ($keyword) {
$tq->where('name', 'like', '%' . $keyword . '%');
});
});
}
// Per-page rule: grid view ALWAYS = 16 (force, ignore client per_page).
$perPage = $request->view === 'grid' ? 16 : ($request->per_page ?? 15);
$items = $query->paginate($perPage);
$view = $request->view === 'grid' ? '_grid' : '_list';
return view('refactor.pages.admin.system-pages.' . $view, compact('items'));
}
/**
* Intermediate "manage" screen: lets admin pick between visual builder
* and the raw HTML editor. Mirrors the list-template pattern.
*/
public function edit(Request $request, $id)
{
$systemTemplate = SystemTemplate::findByUid($id);
if (\Gate::denies('update', $systemTemplate)) {
return $this->notAuthorized();
}
return view('refactor.pages.admin.system-pages.edit', [
'systemTemplate' => $systemTemplate,
]);
}
/**
* Open the visual builder. Blocked when template is in Custom HTML mode.
*/
public function builder(Request $request, $id)
{
$systemTemplate = SystemTemplate::findByUid($id);
if (\Gate::denies('update', $systemTemplate)) {
return $this->notAuthorized();
}
if ($systemTemplate->template?->isUploaded()) {
$request->session()->flash('alert-error', trans('refactor/admin_system_pages.custom_html.builder_blocked'));
return redirect()->route('refactor.admin.system-pages.edit', $systemTemplate->uid);
}
return view('refactor.pages.admin.system-pages.builder', [
'systemTemplate' => $systemTemplate,
'template' => $systemTemplate->template,
'templates' => collect([]),
'tags' => $systemTemplate->getTags(),
]);
}
public function save(Request $request, $id)
{
$systemTemplate = SystemTemplate::findByUid($id);
if (\Gate::denies('update', $systemTemplate)) {
return $this->notAuthorized();
}
// Validate required tags (e.g. {ITEMS} for invoice template)
$missing = [];
foreach ($systemTemplate->requiredTags() as $tag) {
if (!str_contains($request->content ?? '', $tag)) {
$missing[] = $tag;
}
}
if ($missing) {
return response()->json([
'status' => 'error',
'message' => 'Missing required tag(s): ' . implode(', ', $missing),
], 422);
}
$validator = $systemTemplate->template->updateContent($request->json, $request->content);
if ($validator->fails()) {
return response()->json($validator->errors(), 400);
}
return response()->json([
'status' => 'success',
]);
}
/**
* Custom HTML editor: GET renders the dual-mode (TinyMCE + CodeMirror)
* editor; POST persists the HTML and locks the template into uploaded
* mode. Once locked, the visual builder is no longer reachable for this
* template — admin would need to manually clear it from the DB.
*/
public function customHtml(Request $request, $id)
{
$systemTemplate = SystemTemplate::findByUid($id);
if (\Gate::denies('update', $systemTemplate)) {
return $this->notAuthorized();
}
if ($request->isMethod('post')) {
$this->validate($request, ['html' => 'required|string']);
// Required-tag validation (e.g. {ITEMS} for invoice).
$missing = [];
foreach ($systemTemplate->requiredTags() as $tag) {
if (!str_contains($request->html, $tag)) {
$missing[] = $tag;
}
}
if ($missing) {
$msg = trans('refactor/admin_system_pages.custom_html.missing_tags', ['tags' => implode(', ', $missing)]);
if ($request->ajax()) {
return response()->json(['status' => 'error', 'message' => $msg], 422);
}
return back()->withInput()->withErrors(['html' => $msg]);
}
if ($systemTemplate->template?->isUploaded()) {
$systemTemplate->template->updateContent(
\App\Model\Template::DEFAULT_BUILDER_JSON,
$request->html,
);
} else {
\App\Services\TemplateService::for($systemTemplate)
->setCustomHtml($request->html, $systemTemplate->alias);
}
$redirectUrl = route('refactor.admin.system-pages.edit', $systemTemplate->uid);
if ($request->ajax()) {
return response()->json([
'status' => 'success',
'message' => trans('refactor/admin_system_pages.custom_html.saved'),
'redirect' => $redirectUrl,
]);
}
return redirect($redirectUrl);
}
$currentHtml = $systemTemplate->template?->isUploaded()
? ($systemTemplate->template->content ?? '')
: '';
return view('refactor.pages.admin.system-pages.custom_html', [
'systemTemplate' => $systemTemplate,
'currentHtml' => $currentHtml,
]);
}
public function pricingPageBuilder(Request $request)
{
$pricingPageSystemTemplate = SystemTemplate::getPricingPageSystemTemplate();
$pricingListCollection = SystemTemplate::getPricingListCollection();
return view('refactor.pages.admin.system-pages.pricingPageBuilder', [
'pricingPageSystemTemplate' => $pricingPageSystemTemplate,
'template' => $pricingPageSystemTemplate->template,
'pricingListJson' => json_encode($pricingListCollection),
]);
}
}