439 lines
13 KiB
PHP
439 lines
13 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\UserTypes;
|
|
use Hyperf\Codec\Json;
|
|
use Hyperf\Config\Config;
|
|
use Hypervel\Http\Request;
|
|
use Hypervel\Support\Facades\File;
|
|
|
|
use Hypervel\Support\Facades\Auth;
|
|
|
|
use Hypervel\Support\Facades\Response;
|
|
use App\Http\Controllers\Pages\UserModifyAdminPageController;
|
|
use Hypervel\Support\Facades\Storage;
|
|
|
|
use App\Models\SystemSetting;
|
|
use Hyperf\Support\Facades\Logger;
|
|
|
|
|
|
class viewHelperController
|
|
{
|
|
|
|
public static function getDefaultDataVariables(): array
|
|
{
|
|
return [
|
|
'currentUser' => Auth::user(),
|
|
'userModifyAdmin' => new UserModifyAdminPageController(),
|
|
'echo' => [
|
|
'InitializeLoadedFlag' => function () {
|
|
echo '<script> if (typeof DataLoadedFlag === "undefined"){ let DataLoadedFlag = false; } </script>';
|
|
},
|
|
'SetLoadedFlagTrue' => function () {
|
|
echo '<script>if (typeof DataLoadedFlag === "undefined"){ let DataLoadedFlag;} DataLoadedFlag = true; </script>';
|
|
},
|
|
'SetLoadedFlagFalse' => function () {
|
|
echo '<script> if (typeof DataLoadedFlag === "undefined"){ let DataLoadedFlag;} DataLoadedFlag = false; </script>';
|
|
},
|
|
]
|
|
];
|
|
}
|
|
|
|
public static function tryjsondecode($string, $arrayoutput = true)
|
|
{
|
|
if (is_array($string)) {
|
|
return $string;
|
|
}
|
|
if (!$string) {
|
|
return $string;
|
|
}
|
|
$json = json_decode($string, $arrayoutput);
|
|
if ($json === null) {
|
|
return $string;
|
|
} else {
|
|
return $json;
|
|
}
|
|
}
|
|
|
|
public static function tryjsonencode($array)
|
|
{
|
|
if (!$array) {
|
|
return json_encode([]);
|
|
}
|
|
if (is_array($array)) {
|
|
$result = json_encode($array);
|
|
} else {
|
|
$result = json_encode([$array]);
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
public static function getAllViews($path = null, $base = 'resources/views')
|
|
{
|
|
$path = $path ?? base_path($base);
|
|
$views = [];
|
|
|
|
foreach (File::allFiles($path) as $file) {
|
|
$relativePath = $file->getRelativePathname();
|
|
|
|
if (!str_ends_with($relativePath, '.blade.php')) {
|
|
continue;
|
|
}
|
|
|
|
$view = str_replace(['/', '\\'], '.', $relativePath);
|
|
$view = str_replace('.blade.php', '', $view);
|
|
$views[] = $view;
|
|
}
|
|
|
|
return $views;
|
|
}
|
|
|
|
public static function decodeData(string|int|bool|null $data = 0)
|
|
{
|
|
if (is_string($data)) {
|
|
$decodedData = urldecode($data);
|
|
if (str_contains($decodedData, '{')) {
|
|
$val = json_decode($data, true);
|
|
} elseif (str_contains($decodedData, ',')) {
|
|
$decodedData = explode(',', $decodedData);
|
|
$decodedData = self::tryjsonencode($decodedData);
|
|
} else {
|
|
$current_target = $data;
|
|
// $val = ['current_target' => $current_target];
|
|
$decodedData = "'" . $decodedData . "'";
|
|
}
|
|
} else {
|
|
$decodedData = 0;
|
|
}
|
|
|
|
return $decodedData;
|
|
}
|
|
|
|
private static function generatePageHtml(string|array $viewPath, $data, $withTemplate)
|
|
{
|
|
$viewData = [];
|
|
$viewData['FragmentOnly'] = !$withTemplate;
|
|
$viewData['current_target'] = $data;
|
|
$viewData['current_data'] = false;
|
|
$viewData['viewPath'] = $viewPath;
|
|
// $viewMap = config('viewmap.php');
|
|
|
|
if (Auth::check()) {
|
|
$viewData['currentUser'] = Auth::user();
|
|
$viewData['current_user'] = $viewData['currentUser'];
|
|
}
|
|
|
|
|
|
|
|
if (is_array($viewPath)) {
|
|
$closure = $viewPath['data'] ?? null;
|
|
$link = $viewPath['link'] ?? null;
|
|
|
|
$viewData['viewisArray'] = true;
|
|
|
|
if ($closure && $closure instanceof \Closure && is_string($data)) {
|
|
// $viewData['viewisClosure'] = true;
|
|
$current_data = $closure($data);
|
|
$viewData['viewisClosure'] = true;
|
|
} elseif (is_array($data) || is_object($data)) {
|
|
// $viewData['viewisObject'] = true;
|
|
$current_data = $data;
|
|
} else {
|
|
// $viewData['viewisfalse'] = true;
|
|
$current_data = false;
|
|
}
|
|
|
|
$viewPath = $link;
|
|
|
|
|
|
|
|
// file_put_contents('viewvars.txt', print_r(self::getDefaultDataVariables() . $viewData, 1));
|
|
|
|
$viewData = array_merge(self::getDefaultDataVariables(), $viewData);
|
|
|
|
$viewData['current_data'] = $current_data;
|
|
|
|
$pageHtml = view($viewPath, $viewData)->render();
|
|
return $pageHtml;
|
|
}
|
|
|
|
|
|
return view($viewPath, $viewData)->render();
|
|
}
|
|
|
|
private static function generatePageHtmlNew(string|array $viewPath, $data, bool $withTemplate)
|
|
{
|
|
$viewData = [
|
|
'FragmentOnly' => !$withTemplate,
|
|
'current_target' => $data,
|
|
'current_data' => false,
|
|
];
|
|
|
|
// Handle associative array input (with closure support)
|
|
if (is_array($viewPath)) {
|
|
$closure = $viewPath['data'] ?? null;
|
|
$link = $viewPath['link'] ?? null;
|
|
|
|
// Validate
|
|
if (!$link) {
|
|
trigger_error("Missing 'link' key in viewPath array.", E_USER_ERROR);
|
|
}
|
|
|
|
// Execute closure if provided
|
|
if ($closure instanceof \Closure) {
|
|
$current_data = $closure($data);
|
|
} elseif (is_array($data) || is_object($data)) {
|
|
$current_data = $data;
|
|
} else {
|
|
$current_data = false;
|
|
}
|
|
|
|
$viewPath = $link;
|
|
$viewData['current_data'] = $current_data;
|
|
}
|
|
|
|
// Add default + user variables
|
|
$viewData = array_merge(self::getDefaultDataVariables(), $viewData);
|
|
|
|
if (Auth::check()) {
|
|
$viewData['current_user'] = Auth::user();
|
|
}
|
|
|
|
// Render
|
|
try {
|
|
return view($viewPath, $viewData)->render();
|
|
} catch (\Throwable $e) {
|
|
trigger_error("Error rendering view '$viewPath': " . $e->getMessage(), E_USER_ERROR);
|
|
}
|
|
}
|
|
|
|
public function servePageFragmentUnified($page, $data = 0, $withTemplate = false)
|
|
{
|
|
$pagename = $page;
|
|
$val = $data ?? '';
|
|
$loginstatus = Auth::check();
|
|
$viewMap = config('viewmap');
|
|
|
|
// Build list of public pages
|
|
$publicPages = [];
|
|
foreach ($viewMap as $route => $views) {
|
|
if (!empty($views['public'])) {
|
|
$publicPages[] = ltrim($route, '/');
|
|
}
|
|
}
|
|
|
|
// Redirect unauthenticated users trying to access private pages
|
|
if (!$loginstatus && !in_array($pagename, $publicPages)) {
|
|
return response('<script>window.location.href = "/";</script>', 403, ['Content-Type' => 'text/html']);
|
|
}
|
|
|
|
if (!$pagename) {
|
|
return response('Invalid page.', 400);
|
|
}
|
|
|
|
// Backend Interception for Disabled Pages
|
|
if ($this->isPageDisabled($pagename)) {
|
|
if (!$this->canAccessDisabledPage()) {
|
|
// Non-Ultimate users redirect to home (consistent with Vue check)
|
|
return response('<script>window.location.href = "/";</script>', 403, ['Content-Type' => 'text/html']);
|
|
}
|
|
}
|
|
|
|
// Determine user type
|
|
$userType = $loginstatus ? Auth::user()->acct_type->value : 'public';
|
|
|
|
try {
|
|
$viewPath = $viewMap[$pagename][$userType] ?? null;
|
|
} catch (\Throwable $th) {
|
|
$viewPath = null;
|
|
}
|
|
|
|
|
|
|
|
|
|
$viewPathDefault = $viewMap[$pagename]['default'] ?? $viewMap[$pagename]['public'] ?? null;
|
|
|
|
if (!$viewPath && !$viewPathDefault) {
|
|
if (Auth::check() && Auth::user()->acct_type->value === UserTypes::ULTIMATE->value) {
|
|
return response("View for page '{$pagename}' and user type '{$userType}' not found.", 404);
|
|
} else {
|
|
return abort(404, 'Page not found.');
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$viewPath = $viewPath ?: $viewPathDefault;
|
|
|
|
|
|
// if (is_array($viewPath)) {
|
|
// // if (!$data) {
|
|
// // $val = $viewPath['data'] ?? 0;
|
|
// // }
|
|
// $viewPath = $viewPath['link'];
|
|
// }
|
|
|
|
$dontInitializeScript = $userType === 'public'
|
|
? '<script>DontInitialize = 1;</script>'
|
|
: '';
|
|
|
|
$decodedData = self::decodeData($data);
|
|
|
|
|
|
|
|
$pageHtml = self::generatePageHtml($viewPath, $data, $withTemplate);
|
|
|
|
|
|
|
|
if ($withTemplate) {
|
|
|
|
$htmlShell = view('layouts.default')->render();
|
|
$pageHtmlEncoded = base64_encode($pageHtml);
|
|
|
|
$gotoScript = <<<HTML
|
|
<script>
|
|
|
|
$(document).ready(function () {
|
|
fragmentonly = false;
|
|
gotoPage("{$pagename}", {$decodedData}, 0, 1, "{$pageHtmlEncoded}");
|
|
});
|
|
</script>
|
|
HTML;
|
|
|
|
$output = $htmlShell . $dontInitializeScript . $gotoScript;
|
|
} else {
|
|
|
|
$pageHtml .= '<script>window.fragmentonly=true;</script>';
|
|
$output = $pageHtml;
|
|
}
|
|
|
|
return response($output, 200, ['Content-Type' => 'text/html']);
|
|
}
|
|
|
|
|
|
public function servePageFragmentWithTemplate($page, $data = 0)
|
|
{
|
|
return $this->servePageFragmentUnified($page, $data, true);
|
|
}
|
|
|
|
public function servePageFragment($page, $data = 0)
|
|
{
|
|
return $this->servePageFragmentUnified($page, $data, false);
|
|
}
|
|
|
|
|
|
// public function servePageFragment($page, $data=0)
|
|
// {
|
|
// $pagename = $page;
|
|
// $val = $data ?? '';
|
|
// $loginstatus = Auth::check();
|
|
// $viewMap = config('viewmap');
|
|
// $publicPages = [];
|
|
|
|
// foreach ($viewMap as $route => $views) {
|
|
// if (!empty($views['public'])) {
|
|
// $publicPages[] = ltrim($route, '/');
|
|
// }
|
|
// }
|
|
|
|
|
|
// if (!$loginstatus && !in_array($pagename, $publicPages)) {
|
|
// return response('<script>window.location.href = "/";</script>', 403);
|
|
// }
|
|
|
|
// if (!$pagename) {
|
|
// return response('Invalid page.', 400);
|
|
// }
|
|
|
|
|
|
// $userType = $loginstatus ? (Auth::user()->acct_type ?? 'default') : 'public';
|
|
|
|
|
|
// $viewPath = $viewMap[$pagename][$userType] ?? null;
|
|
|
|
// if (!$viewPath) {
|
|
// return response("View for page '{$pagename}' and user type '{$userType}' not found.", 404);
|
|
// }
|
|
|
|
// // Optional: flag to prevent initialization on public pages
|
|
// $dontInitializeScript = '';
|
|
// if ($userType === 'public') {
|
|
// $dontInitializeScript = '<script>DontInitialize = 1;</script>';
|
|
// }
|
|
|
|
// // Process the `$data` parameter
|
|
// if (is_string($val)){
|
|
// $decodedData = urldecode($val);
|
|
// if (str_contains($decodedData, '{')) {
|
|
// // Assume it's already JSON
|
|
// } elseif (str_contains($decodedData, ',')) {
|
|
// $decodedData = explode(',', $decodedData);
|
|
// $decodedData = tryjsonencode($decodedData);
|
|
// } else {
|
|
// $decodedData = "'" . $decodedData . "'";
|
|
// }}else{
|
|
// $decodedData=0;
|
|
// }
|
|
|
|
// // Load HTML shell layout (starter page)
|
|
// $htmlShell = view('layouts.default')->render();
|
|
|
|
// // Load the page fragment's view content
|
|
// $pageHtml = view($viewPath)->render();
|
|
// $pageHtmlEncoded = base64_encode($pageHtml);
|
|
|
|
// // Inject script to trigger JS-side page rendering
|
|
// $gotoScript = <<<HTML
|
|
// <script>
|
|
// $(document).ready(function () {
|
|
// gotoPage("{$pagename}", {$decodedData}, 0, 0, `{$pageHtmlEncoded}`);
|
|
// });
|
|
// </script>
|
|
// HTML;
|
|
|
|
// // Return the full response
|
|
// return response($htmlShell . $dontInitializeScript . $gotoScript, 200, ['Content-Type' => 'text/html']);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Check if a page is disabled via system setting.
|
|
*/
|
|
private function isPageDisabled(string $pageName): bool
|
|
{
|
|
$disabledPages = SystemSetting::getValue('disabled_pages', []);
|
|
|
|
if (empty($disabledPages) || !is_array($disabledPages)) {
|
|
return false;
|
|
}
|
|
|
|
// Case-insensitive match
|
|
return in_array(strtolower($pageName), array_map('strtolower', $disabledPages));
|
|
}
|
|
|
|
/**
|
|
* Check if current user can access disabled pages (Ultimate only).
|
|
*/
|
|
private function canAccessDisabledPage(): bool
|
|
{
|
|
if (!Auth::user()) {
|
|
return false;
|
|
}
|
|
|
|
$user = Auth::user();
|
|
return isset($user->acct_type) && $user->acct_type->value === UserTypes::ULTIMATE->value;
|
|
}
|
|
|
|
|
|
}
|