Allow heading tags (h1-h6) in ContentSanitizer so news editor headings render

This commit is contained in:
2026-06-04 07:52:57 +02:00
parent 0b33a1b074
commit 15870ddb1f
191 changed files with 15453 additions and 1786 deletions

View File

@@ -92,6 +92,121 @@ final class AcademyAccessService
return $this->activeAcademySubscription($user) instanceof Subscription;
}
/**
* @return array<string, mixed>
*/
public function accessSummary(?User $user): array
{
if (! $user instanceof User) {
return [
'signedIn' => false,
'tier' => 'free',
'tierLabel' => 'Guest',
'hasPaidAccess' => false,
'status' => 'guest',
'statusLabel' => 'Preview access only',
'expiresAt' => null,
'dateLabel' => null,
'renewsAutomatically' => false,
'source' => 'none',
];
}
if ($this->isAcademyAdmin($user)) {
return [
'signedIn' => true,
'tier' => 'admin',
'tierLabel' => 'Admin',
'hasPaidAccess' => true,
'status' => 'staff_access',
'statusLabel' => 'Full staff access',
'expiresAt' => null,
'dateLabel' => null,
'renewsAutomatically' => false,
'source' => 'admin',
];
}
$tier = $this->currentTier($user);
$subscription = $this->activeAcademySubscription($user);
if ($subscription instanceof Subscription) {
$trialEndsAt = $subscription->trial_ends_at?->toISOString();
$endsAt = $subscription->ends_at?->toISOString();
if ($subscription->onGracePeriod()) {
return [
'signedIn' => true,
'tier' => $tier,
'tierLabel' => $this->tierLabel($tier),
'hasPaidAccess' => $tier !== 'free',
'status' => 'grace_period',
'statusLabel' => 'Cancels soon',
'expiresAt' => $endsAt,
'dateLabel' => 'Access ends',
'renewsAutomatically' => false,
'source' => 'subscription',
];
}
if ($subscription->onTrial()) {
return [
'signedIn' => true,
'tier' => $tier,
'tierLabel' => $this->tierLabel($tier),
'hasPaidAccess' => $tier !== 'free',
'status' => 'trialing',
'statusLabel' => 'Trial active',
'expiresAt' => $trialEndsAt,
'dateLabel' => 'Trial ends',
'renewsAutomatically' => ! $subscription->cancelled(),
'source' => 'subscription',
];
}
return [
'signedIn' => true,
'tier' => $tier,
'tierLabel' => $this->tierLabel($tier),
'hasPaidAccess' => $tier !== 'free',
'status' => 'active',
'statusLabel' => 'Renews automatically',
'expiresAt' => null,
'dateLabel' => null,
'renewsAutomatically' => true,
'source' => 'subscription',
];
}
if ($tier !== 'free') {
return [
'signedIn' => true,
'tier' => $tier,
'tierLabel' => $this->tierLabel($tier),
'hasPaidAccess' => true,
'status' => 'active',
'statusLabel' => 'Full access active',
'expiresAt' => null,
'dateLabel' => null,
'renewsAutomatically' => false,
'source' => 'legacy_role',
];
}
return [
'signedIn' => true,
'tier' => 'free',
'tierLabel' => 'Free',
'hasPaidAccess' => false,
'status' => 'free',
'statusLabel' => 'Free access',
'expiresAt' => null,
'dateLabel' => null,
'renewsAutomatically' => false,
'source' => 'none',
];
}
public function canAccessLesson(?User $user, AcademyLesson $lesson): bool
{
return $this->canAccessContent($user, (string) $lesson->access_level);
@@ -633,6 +748,16 @@ final class AcademyAccessService
};
}
private function tierLabel(string $tier): string
{
return match ($this->normalizeAccessLevel($tier)) {
'admin' => 'Admin',
'pro' => 'Pro',
'creator' => 'Creator',
default => 'Free',
};
}
private function isAcademyAdmin(User $user): bool
{
return $user->hasStaffAccess() || $user->isModerator();