File: /home/xedaptot/be.naniguide.com/app/Http/Controllers/Refactor/Admin/SettingController.php
<?php
namespace App\Http\Controllers\Refactor\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Model\Setting;
use App\Library\UpgradeManager;
use App\Helpers\LicenseHelper;
use App\Notifications\Admin\UpgradePatchAvailable;
use App\Notifications\System\SystemUrlMismatch;
use App\Services\Notifications\Notifier;
use Illuminate\Support\Facades\Log;
use App;
class SettingController extends Controller
{
public function index(Request $request)
{
$admin = $request->user()->admin;
if ($admin->getPermission('setting_general') == 'yes') {
return redirect()->route('refactor.admin.settings.general');
}
if ($admin->getPermission('setting_system_urls') == 'yes') {
return redirect()->route('refactor.admin.settings.urls');
}
if ($admin->getPermission('setting_background_job') == 'yes') {
return redirect()->route('refactor.admin.settings.cronjob');
}
return $this->notAuthorized();
}
public function general(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return $this->notAuthorized();
}
if ($request->isMethod('post')) {
// Read settings from either JSON body or settings[] wrapper (for file uploads)
if ($request->isJson()) {
$settings = $request->except(['_token']);
} else {
// FormData with settings[] wrapper preserves dot-notation keys
$settings = $request->input('settings', []);
}
foreach ($settings as $name => $value) {
if (is_array($value)) {
continue;
}
Setting::set($name, $value);
}
// Handle file uploads by known field names
foreach (['site_logo_light', 'site_logo_dark', 'site_favicon'] as $fileField) {
if ($request->hasFile($fileField) && $request->file($fileField)->isValid()) {
Setting::uploadFile($request->file($fileField), $fileField, false);
}
}
if ($request->ajax()) {
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.flash.saved')]);
}
$request->session()->flash('alert-success', trans('refactor/admin_settings.flash.saved'));
return redirect()->route('refactor.admin.settings.general');
}
$settings = Setting::getAll();
$tab = 'general';
return view('refactor.pages.admin.settings.general', compact('settings', 'tab'));
}
public function mailer(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return $this->notAuthorized();
}
if ($request->isMethod('post')) {
$data = $request->isJson() ? $request->except(['_token']) : $request->input('settings', $request->except(['_token']));
foreach ($data as $name => $value) {
if (!is_array($value)) {
Setting::set($name, $value);
}
}
if ($request->ajax()) {
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.flash.saved')]);
}
$request->session()->flash('alert-success', trans('refactor/admin_settings.flash.saved'));
return redirect()->route('refactor.admin.settings.mailer');
}
$settings = Setting::getAll();
$tab = 'mailer';
return view('refactor.pages.admin.settings.mailer', compact('settings', 'tab'));
}
public function mailerTest(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return response()->json(['status' => 'error', 'message' => 'Not authorized'], 403);
}
try {
$email = new \Symfony\Component\Mime\Email();
$email->subject($request->input('subject'));
$email->to($request->input('to_email'));
$email->html($request->input('content'));
$mailer = App::make('xmailer');
$mailer->sendWithDefaultFromAddress($email);
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.flash.test_sent')]);
} catch (\Exception $e) {
return response()->json(['status' => 'error', 'message' => trans('refactor/admin_settings.mailer.test_error', ['error' => $e->getMessage()])], 400);
}
}
public function cronjob(Request $request)
{
if ($request->user()->admin->getPermission('setting_background_job') != 'yes') {
return $this->notAuthorized();
}
if ($request->isMethod('post')) {
$phpPath = $request->input('php_bin_path');
$phpPathValue = $request->input('php_bin_path_value');
if ($phpPath === 'manual' || empty($phpPath)) {
$phpPath = $phpPathValue;
}
if (empty($phpPath)) {
$errorMsg = trans('refactor/admin_settings.cronjob.path_required');
if ($request->ajax()) {
return response()->json(['status' => 'error', 'message' => $errorMsg], 422);
}
return redirect()->route('refactor.admin.settings.cronjob')->withErrors(['php_bin_path' => $errorMsg]);
}
// Validate PHP binary path
$check = \App\Library\Tool::checkPHPBinPath($phpPath);
if ($check != 'ok') {
if ($request->ajax()) {
return response()->json(['status' => 'error', 'message' => $check], 422);
}
return redirect()->route('refactor.admin.settings.cronjob')->withErrors(['php_bin_path' => $check]);
}
Setting::set('php_bin_path', $phpPath);
if ($request->ajax()) {
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.flash.saved')]);
}
$request->session()->flash('alert-success', trans('refactor/admin_settings.flash.saved'));
return redirect()->route('refactor.admin.settings.cronjob');
}
// Detect PHP paths
$paths = ['/usr/local/bin/php', '/usr/bin/php', '/bin/php', '/usr/bin/php8.1', '/usr/bin/php8.2', '/usr/bin/php8.3'];
if (exec_enabled()) {
try {
$detected = explode(' ', exec('whereis php'));
$paths = array_unique(array_merge($paths, $detected));
} catch (\Exception $e) {
// skip
}
}
$php_paths = array_values(array_filter($paths, function ($path) {
try {
return is_executable($path) && preg_match("/php[0-9\.a-z]{0,3}$/i", $path);
} catch (\Exception $ex) {
return false;
}
}));
$php_bin_path_value = Setting::get('php_bin_path');
if (empty($php_bin_path_value)) {
$php_bin_path_value = !empty($php_paths) ? $php_paths[0] : '/usr/bin/php';
}
$settings = Setting::getAll();
$tab = 'cronjob';
return view('refactor.pages.admin.settings.cronjob', compact('settings', 'tab', 'php_paths', 'php_bin_path_value'));
}
public function urls(Request $request)
{
if ($request->user()->admin->getPermission('setting_system_urls') != 'yes') {
return $this->notAuthorized();
}
$urlSettings = array_filter(Setting::getAll(), function ($setting, $key) {
return in_array($key, [
'url_unsubscribe',
'url_open_track',
'url_click_track',
'url_update_profile',
'url_web_view',
]);
}, ARRAY_FILTER_USE_BOTH);
$current = url('/');
$cached = config('app.url');
$matched = ($cached == $current);
$settings = Setting::getAll();
$tab = 'urls';
return view('refactor.pages.admin.settings.urls', compact('settings', 'tab', 'urlSettings', 'matched', 'current', 'cached'));
}
public function urlsUpdate(Request $request)
{
if ($request->user()->admin->getPermission('setting_system_urls') != 'yes') {
return response()->json(['status' => 'error', 'message' => 'Not authorized'], 403);
}
\App\Helpers\reset_app_url(true);
if (file_exists(base_path('bootstrap/cache/config.php'))) {
unlink(base_path('bootstrap/cache/config.php'));
}
// Display-only template — signed routes embed a per-URL HMAC so we
// can't use route() with placeholder values. Show the path shape with
// a SIGNATURE token for admin reference.
Setting::set('url_unsubscribe', rtrim(url('/'), '/') . '/c/SUBSCRIBER/unsubscribe-form/MESSAGE_ID?signature=SIGNATURE');
Setting::set('url_open_track', route('openTrackingUrl', ['message_id' => 'MESSAGE_ID']));
Setting::set('url_click_track', route('clickTrackingUrl', ['message_id' => 'MESSAGE_ID', 'url' => 'URL']));
// Wave F: `url_delivery_handler` removed — see InstallController note.
Setting::set('url_update_profile', action('Pub\MailListController@profileUpdateForm', [
'list_uid' => 'LIST_UID',
'id' => 'SUBSCRIBER_ID',
'customer_uid' => 'CUSTOMER_UID',
]));
Setting::set('url_web_view', route('webViewerUrl', ['message_id' => 'MESSAGE_ID']));
$current = url('/');
$cached = config('app.url');
$notifier = app(Notifier::class);
if ($current === $cached) {
$notifier->clearGroup('system-url-mismatch');
} else {
$notifier->shareWithAdmins(new SystemUrlMismatch($current, $cached));
}
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.urls.updated')]);
}
public function advanced(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return $this->notAuthorized();
}
$settings = Setting::getAll();
$tab = 'advanced';
return view('refactor.pages.admin.settings.advanced', compact('settings', 'tab'));
}
public function advancedUpdate(Request $request, $name)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return response()->json(['status' => 'error', 'message' => 'Not authorized'], 403);
}
Setting::set($name, $request->input('value'));
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.advanced.updated', ['name' => $name])]);
}
public function license(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return $this->notAuthorized();
}
$license_error = '';
if ($request->isMethod('post')) {
try {
LicenseHelper::updateLicense($request->license);
if ($request->ajax()) {
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.license.verified')]);
}
$request->session()->flash('alert-success', trans('refactor/admin_settings.license.verified'));
return redirect()->route('refactor.admin.settings.license');
} catch (\Throwable $ex) {
$license_error = $ex->getMessage();
if ($request->ajax()) {
return response()->json(['status' => 'error', 'message' => trans('refactor/admin_settings.license.error', ['error' => $license_error])]);
}
}
}
$license = LicenseHelper::getCurrentLicense();
$settings = Setting::getAll();
$tab = 'license';
return view('refactor.pages.admin.settings.license', compact('settings', 'tab', 'license', 'license_error'));
}
public function licenseRefresh(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return response()->json(['status' => 'error', 'message' => 'Not authorized'], 403);
}
try {
LicenseHelper::refreshLicense();
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.license.refreshed')]);
} catch (\Exception $e) {
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
}
public function licenseRemove(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return response()->json(['status' => 'error', 'message' => 'Not authorized'], 403);
}
try {
LicenseHelper::removeLicense();
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.license.removed')]);
} catch (\Exception $e) {
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
}
public function upgrade(Request $request)
{
session(['secret' => $request->input('secret')]);
$manager = new UpgradeManager();
$license = LicenseHelper::getCurrentLicense();
$settings = Setting::getAll();
$tab = 'upgrade';
return view('refactor.pages.admin.settings.upgrade', compact('settings', 'tab', 'manager', 'license'))->with([
'phpversion' => version_compare(PHP_VERSION, config('custom.php_recommended'), '>='),
'failed' => null,
]);
}
public function doUpgrade(Request $request)
{
$manager = new UpgradeManager();
$failed = $manager->test();
if (!empty($failed)) {
if ($request->ajax() || $request->expectsJson()) {
return response()->json([
'status' => 'error',
'step' => 'apply',
'message' => trans('refactor/admin_settings.upgrade.cannot_write'),
'failed' => array_values($failed),
], 400);
}
$license = LicenseHelper::getCurrentLicense();
$settings = Setting::getAll();
$tab = 'upgrade';
return view('refactor.pages.admin.settings.upgrade', compact('settings', 'tab', 'manager', 'license', 'failed'))->with([
'phpversion' => version_compare(PHP_VERSION, config('custom.php_recommended'), '>='),
]);
}
try {
$manager->run();
} catch (\Throwable $e) {
Log::error('Upgrade apply failed: ' . $e->getMessage());
if ($request->ajax() || $request->expectsJson()) {
return response()->json([
'status' => 'error',
'step' => 'apply',
'message' => $e->getMessage(),
], 500);
}
$request->session()->flash('alert-error', $e->getMessage());
return redirect()->route('refactor.admin.settings.upgrade');
}
$request->session()->put('upgraded', true);
if ($request->ajax() || $request->expectsJson()) {
return response()->json([
'status' => 'success',
'step' => 'apply',
]);
}
$pageUrl = url('/migrate/run');
echo '<html><head><meta http-equiv="refresh" content="3;'.$pageUrl.'" /><title>Upgrading...</title></head><body>Upgrade is in progress, please wait...</body></html>';
return;
}
public function cancelUpgrade(Request $request)
{
try {
$manager = new UpgradeManager();
$manager->cleanup();
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.upgrade.cancelled')]);
} catch (\Exception $e) {
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
}
public function uploadPatch(Request $request)
{
if (is_null(LicenseHelper::getCurrentLicense())) {
if ($request->ajax()) {
return response()->json(['status' => 'error', 'message' => trans('refactor/admin_settings.upgrade.license_required')], 400);
}
$request->session()->flash('alert-error', trans('refactor/admin_settings.upgrade.license_required'));
return redirect()->route('refactor.admin.settings.upgrade');
}
try {
$manager = new UpgradeManager();
$request->file('file')->move(storage_path('tmp'), $request->file('file')->getClientOriginalName());
$path = storage_path('tmp/' . $request->file('file')->getClientOriginalName());
$manager->load($path);
app(Notifier::class)->dispatch(new UpgradePatchAvailable(
newVersion: (string) $manager->getNewVersion(),
currentVersion: (string) $manager->getCurrentVersion(),
));
if ($request->ajax()) {
return response()->json([
'status' => 'success',
'message' => trans('refactor/admin_settings.upgrade.upload_success'),
'attachment' => [
'uid' => uniqid(),
'name' => $request->file('file')->getClientOriginalName(),
'size' => 0,
'mime_type' => 'application/zip',
],
]);
}
$request->session()->flash('alert-success', trans('messages.upgrade.alert.upload_success'));
} catch (\Exception $e) {
Log::info('Upgrade failed. ' . $e->getMessage());
if ($request->ajax()) {
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
$request->session()->flash('alert-error', $e->getMessage());
}
return redirect()->route('refactor.admin.settings.upgrade');
}
public function downloadPatchFromUrl(Request $request)
{
if (is_null(LicenseHelper::getCurrentLicense())) {
return response()->json(['status' => 'error', 'message' => trans('refactor/admin_settings.upgrade.license_required')], 400);
}
$url = $request->input('url');
if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) {
return response()->json(['status' => 'error', 'message' => trans('refactor/admin_settings.upgrade.invalid_url')], 400);
}
// Only allow http/https
$scheme = parse_url($url, PHP_URL_SCHEME);
if (!in_array($scheme, ['http', 'https'])) {
return response()->json(['status' => 'error', 'message' => trans('refactor/admin_settings.upgrade.invalid_url')], 400);
}
// Patch files can be up to 200MB — allow enough time for download + extract
set_time_limit(600);
try {
$filename = basename(parse_url($url, PHP_URL_PATH)) ?: 'patch.zip';
// Ensure .zip extension
if (!str_ends_with(strtolower($filename), '.zip')) {
$filename .= '.zip';
}
$tmpPath = storage_path('tmp/' . $filename);
$manager = new UpgradeManager();
$manager->downloadPatchTo($url, $tmpPath, ['timeout' => 600]);
$manager->load($tmpPath);
app(Notifier::class)->dispatch(new UpgradePatchAvailable(
newVersion: (string) $manager->getNewVersion(),
currentVersion: (string) $manager->getCurrentVersion(),
));
return response()->json([
'status' => 'success',
'message' => trans('refactor/admin_settings.upgrade.download_success'),
]);
} catch (\Exception $e) {
Log::info('Upgrade download from URL failed. ' . $e->getMessage());
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
}
public function payment(Request $request)
{
if ($request->user()->admin->getPermission('setting_general') != 'yes') {
return $this->notAuthorized();
}
if ($request->isMethod('post')) {
$data = $request->isJson() ? $request->except(['_token']) : $request->input('settings', $request->except(['_token']));
foreach ($data as $name => $value) {
if (!is_array($value)) {
Setting::set($name, $value);
}
}
if ($request->ajax()) {
return response()->json(['status' => 'success', 'message' => trans('refactor/admin_settings.flash.saved')]);
}
$request->session()->flash('alert-success', trans('refactor/admin_settings.flash.saved'));
return redirect()->route('refactor.admin.settings.payment');
}
$settings = Setting::getAll();
$tab = 'payment';
return view('refactor.pages.admin.settings.payment', compact('settings', 'tab'));
}
public function logs(Request $request)
{
$logFile = storage_path('logs/laravel.log');
$error_logs = '';
if (file_exists($logFile)) {
$file = file($logFile);
$lines = 300;
for ($i = max(0, count($file) - $lines); $i < count($file); ++$i) {
$error_logs .= $file[$i];
}
}
$settings = Setting::getAll();
$tab = 'logs';
return view('refactor.pages.admin.settings.logs', compact('settings', 'tab', 'error_logs'));
}
}