php-content/Controllers/ContentPreviewController.php
2026-01-26 23:59:46 +00:00

102 lines
3.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Core\Content\Controllers;
use Core\Mod\Tenant\Models\Workspace;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Core\Content\Models\ContentItem;
/**
* ContentPreviewController - Preview draft content before publishing.
*
* Provides time-limited shareable preview URLs for draft, scheduled,
* and private content items.
*/
class ContentPreviewController extends Controller
{
/**
* Generate a preview link for a content item.
*
* Requires authentication and access to the content's workspace.
*/
public function generateLink(Request $request, ContentItem $item): JsonResponse
{
// Verify user has access to this workspace
$user = $request->user();
if (! $user || ! $this->userCanAccessWorkspace($user, $item->workspace_id)) {
return response()->json([
'error' => 'Unauthorised access to this content item.',
], 403);
}
$hours = (int) $request->input('hours', 24);
$hours = min(max($hours, 1), 168); // Between 1 hour and 7 days
$token = $item->generatePreviewToken($hours);
$previewUrl = route('content.preview', [
'item' => $item->id,
'token' => $token,
]);
return response()->json([
'preview_url' => $previewUrl,
'expires_at' => $item->preview_expires_at->toIso8601String(),
'expires_in' => $item->getPreviewTokenTimeRemaining(),
]);
}
/**
* Revoke the preview token for a content item.
*/
public function revokeLink(Request $request, ContentItem $item): JsonResponse
{
// Verify user has access to this workspace
$user = $request->user();
if (! $user || ! $this->userCanAccessWorkspace($user, $item->workspace_id)) {
return response()->json([
'error' => 'Unauthorised access to this content item.',
], 403);
}
$item->revokePreviewToken();
return response()->json([
'message' => 'Preview link revoked successfully.',
]);
}
/**
* Check if a user can access a workspace.
*/
protected function userCanAccessWorkspace($user, int $workspaceId): bool
{
// Check if user owns the workspace or is a member
$workspace = Workspace::find($workspaceId);
if (! $workspace) {
return false;
}
// User owns workspace
if ($workspace->user_id === $user->id) {
return true;
}
// User is workspace member (if membership system exists)
if (method_exists($user, 'workspaces')) {
return $user->workspaces()->where('workspaces.id', $workspaceId)->exists();
}
// Fallback: check if user has any content in this workspace
return ContentItem::where('workspace_id', $workspaceId)
->where(function ($query) use ($user) {
$query->where('author_id', $user->id)
->orWhere('last_edited_by', $user->id);
})
->exists();
}
}