Fix views inconsistencies

This commit is contained in:
DariusIII
2026-08-09 14:37:39 +02:00
parent 73e5294132
commit f1912e5e74
117 changed files with 3587 additions and 3384 deletions
+50 -1
View File
@@ -95,7 +95,8 @@ if (! function_exists('makeFieldLinks')) {
if ($i > 7) {
break;
}
$newArr[] = '<a href="'.url('/'.ucfirst($type).'?'.$field.'='.urlencode($ta)).'" title="'.$ta.'">'.$ta.'</a>';
$escaped = e($ta);
$newArr[] = '<a href="'.url('/'.ucfirst($type).'?'.$field.'='.urlencode($ta)).'" title="'.$escaped.'">'.$escaped.'</a>';
$i++;
}
@@ -693,6 +694,54 @@ if (! function_exists('formatBytes')) {
}
}
if (! function_exists('formatDate')) {
/**
* Format a date as Y-m-d (house date style).
*/
function formatDate(Carbon|DateTimeInterface|string|null $date): string
{
if ($date === null || $date === '') {
return '';
}
$date = $date instanceof DateTimeInterface ? $date : Carbon::parse($date);
return $date->format('Y-m-d');
}
}
if (! function_exists('formatDateTime')) {
/**
* Format a date as Y-m-d H:i (house datetime style).
*/
function formatDateTime(Carbon|DateTimeInterface|string|null $date): string
{
if ($date === null || $date === '') {
return '';
}
$date = $date instanceof DateTimeInterface ? $date : Carbon::parse($date);
return $date->format('Y-m-d H:i');
}
}
if (! function_exists('formatDateTimeSeconds')) {
/**
* Format a date as Y-m-d H:i:s (house datetime style with seconds).
*/
function formatDateTimeSeconds(Carbon|DateTimeInterface|string|null $date): string
{
if ($date === null || $date === '') {
return '';
}
$date = $date instanceof DateTimeInterface ? $date : Carbon::parse($date);
return $date->format('Y-m-d H:i:s');
}
}
if (! function_exists('csp_nonce')) {
/**
* Generate a CSP nonce for inline scripts
+18 -1
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\Country;
use App\Models\DnzbFailure;
use App\Models\Predb;
use App\Models\Release;
@@ -109,7 +110,7 @@ class DetailsController extends BasePageController
if (Settings::settingValue('trailers_display')) {
$trailer = empty($mov['trailer']) ? $this->movieService->getTrailer($data['imdbid']) : $mov['trailer'];
if ($trailer) {
$mov['trailer'] = sprintf('<iframe width="%d" height="%d" src="%s"></iframe>', Settings::settingValue('trailers_size_x'), Settings::settingValue('trailers_size_y'), $trailer);
$mov['trailer'] = sprintf('<iframe width="%d" height="%d" src="%s"></iframe>', Settings::settingValue('trailers_size_x'), Settings::settingValue('trailers_size_y'), e($trailer));
}
}
}
@@ -158,6 +159,20 @@ class DetailsController extends BasePageController
$pre = Predb::getForRelease($data['predb_id']);
// Resolve AniDB country code to a Country model/name here so the view stays query-free
$anidbCountryCode = null;
if (is_object($AniDBAPIArray)) {
$anidbCountryCode = $AniDBAPIArray->country ?? null;
} elseif (is_array($AniDBAPIArray)) {
$anidbCountryCode = $AniDBAPIArray['country'] ?? null;
}
$anidbCountryModel = null;
$anidbCountryName = null;
if (! empty($anidbCountryCode)) {
$anidbCountryModel = Country::query()->find($anidbCountryCode);
$anidbCountryName = $anidbCountryModel->name ?? $anidbCountryCode;
}
$this->viewData = array_merge($this->viewData, [
'release' => $data,
'reVideo' => $reVideo,
@@ -166,6 +181,8 @@ class DetailsController extends BasePageController
'show' => $showInfo,
'movie' => $mov,
'anidb' => $AniDBAPIArray,
'anidbCountryModel' => $anidbCountryModel,
'anidbCountryName' => $anidbCountryName,
'music' => $mus,
'con' => $con,
'game' => $game,
@@ -181,6 +181,11 @@ class ProfileController extends BasePageController
}
}
// Keep the composer's cached per-user data in sync with theme changes
if ($request->hasAny(['theme_preference', 'color_scheme'])) {
Cache::forget('composer_user_'.$userid);
}
// Update timezone preference
if ($request->has('timezone')) {
$timezoneValue = $request->input('timezone');
@@ -305,6 +310,9 @@ class ProfileController extends BasePageController
}
$user->save();
// Keep the composer's cached per-user data in sync with theme changes
Cache::forget('composer_user_'.$user->id);
return response()->json([
'success' => true,
'theme_preference' => $user->theme_preference,
+53
View File
@@ -6,6 +6,7 @@ namespace App\Models;
use App\Enums\UserRole;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
/**
@@ -201,4 +202,56 @@ class Content extends Model
{
return $this->contenttype === self::TYPE_INDEX;
}
/**
* Resolve the content URL: external URLs are used as-is (domains without
* protocol get https://), internal paths are prefixed with the site URL.
*
* @return Attribute<string|null, never>
*/
protected function resolvedUrl(): Attribute
{
return Attribute::make(
get: function (): ?string {
$url = $this->url;
if (empty($url)) {
return null;
}
if (str_starts_with($url, 'http://') || str_starts_with($url, 'https://')) {
return $url;
}
// Domain pattern without protocol (e.g. google.com, chatgpt.ai)
if (! str_starts_with($url, '/') && preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}/', $url)) {
return 'https://'.$url;
}
return url($url);
}
);
}
/**
* Whether the content URL points to an external site.
*
* @return Attribute<bool, never>
*/
protected function isExternalUrl(): Attribute
{
return Attribute::make(
get: function (): bool {
$url = $this->url;
if (empty($url)) {
return false;
}
return str_starts_with($url, 'http://')
|| str_starts_with($url, 'https://')
|| (! str_starts_with($url, '/') && preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}/', $url));
}
);
}
}
+2
View File
@@ -38,6 +38,8 @@ class AdminDataComposer
'loggedin' => $user !== null,
'isadmin' => $isNntmuxUser && $user->hasRole('Admin'),
'ismod' => $isNntmuxUser && $user->hasRole('Moderator'),
'userTheme' => $isNntmuxUser ? ($user->theme_preference ?? 'light') : 'light',
'userColorScheme' => $isNntmuxUser ? ($user->color_scheme ?? 'blue') : 'blue',
]);
}
@@ -97,12 +97,16 @@ class GlobalDataComposer
'ismod' => $userdata->hasRole('Moderator'),
'parentcatlist' => $parentcatlist,
'header_menu_cat' => request()->input('t', ''),
'userTheme' => $userdata->theme_preference ?? 'light',
'userColorScheme' => $userdata->color_scheme ?? 'blue',
]);
} else {
$viewData = array_merge($viewData, [
'isadmin' => false,
'ismod' => false,
'loggedin' => false,
'userTheme' => 'light',
'userColorScheme' => 'blue',
]);
}