implement featured post admin endpoints
Adds POST /admin/posts/feature, POST /admin/posts/unfeature (both auth-required, admin-checked inside controller via the use case's ForbiddenException), and public GET /posts/featured. Post serialization now includes featureSlot.
This commit is contained in:
parent
8983b69fa1
commit
8ac5a5b18a
2 changed files with 85 additions and 1 deletions
|
|
@ -5,15 +5,20 @@ namespace App\Controllers;
|
|||
use App\Exceptions\BadRequestException;
|
||||
use App\Exceptions\ForbiddenException;
|
||||
use App\Post\Post;
|
||||
use App\Post\UseCases\ClearFeaturedPost\ClearFeaturedPost;
|
||||
use App\Post\UseCases\ClearFeaturedPost\ClearFeaturedPostRequest;
|
||||
use App\Post\UseCases\CreatePost\CreatePost;
|
||||
use App\Post\UseCases\CreatePost\CreatePostRequest;
|
||||
use App\Post\UseCases\DeletePost\DeletePost;
|
||||
use App\Post\UseCases\DeletePost\DeletePostRequest;
|
||||
use App\Post\UseCases\GetPost\GetPost;
|
||||
use App\Post\UseCases\ListFeaturedPosts\ListFeaturedPosts;
|
||||
use App\Post\UseCases\ListRecentPosts\ListRecentPosts;
|
||||
use App\Post\UseCases\ListRecentPosts\ListRecentPostsRequest;
|
||||
use App\Post\UseCases\ListUserPosts\ListUserPosts;
|
||||
use App\Post\UseCases\ListUserPosts\ListUserPostsRequest;
|
||||
use App\Post\UseCases\SetFeaturedPost\SetFeaturedPost;
|
||||
use App\Post\UseCases\SetFeaturedPost\SetFeaturedPostRequest;
|
||||
use App\User\User;
|
||||
use App\User\UserRepository;
|
||||
use DomainException;
|
||||
|
|
@ -30,6 +35,9 @@ class PostController
|
|||
private GetPost $getPost,
|
||||
private ListRecentPosts $listRecentPosts,
|
||||
private ListUserPosts $listUserPosts,
|
||||
private SetFeaturedPost $setFeaturedPost,
|
||||
private ClearFeaturedPost $clearFeaturedPost,
|
||||
private ListFeaturedPosts $listFeaturedPosts,
|
||||
private UserRepository $userRepo,
|
||||
) {}
|
||||
|
||||
|
|
@ -126,6 +134,75 @@ class PostController
|
|||
], 201);
|
||||
}
|
||||
|
||||
public function listFeatured(Request $request): JsonResponse
|
||||
{
|
||||
$posts = $this->listFeaturedPosts->execute();
|
||||
|
||||
return new JsonResponse([
|
||||
'posts' => array_map(
|
||||
function (Post $post) {
|
||||
return $this->serialize($post);
|
||||
},
|
||||
$posts,
|
||||
),
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function feature(Request $request): JsonResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $request->attributes->get('user');
|
||||
try {
|
||||
$post = $this->setFeaturedPost->execute(
|
||||
new SetFeaturedPostRequest(
|
||||
postId: (int) $request->input('postId'),
|
||||
slot: (int) $request->input('slot'),
|
||||
requesterIsAdmin: $user->isAdmin(),
|
||||
),
|
||||
);
|
||||
} catch (BadRequestException $exception) {
|
||||
return new JsonResponse(
|
||||
['error' => $exception->getMessage()], 400,
|
||||
);
|
||||
} catch (ForbiddenException $exception) {
|
||||
return new JsonResponse(
|
||||
['error' => $exception->getMessage()], 403,
|
||||
);
|
||||
} catch (DomainException $exception) {
|
||||
return new JsonResponse(
|
||||
['error' => $exception->getMessage()], 404,
|
||||
);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'post' => $this->serialize($post),
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function unfeature(Request $request): JsonResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $request->attributes->get('user');
|
||||
try {
|
||||
$this->clearFeaturedPost->execute(
|
||||
new ClearFeaturedPostRequest(
|
||||
postId: (int) $request->input('postId'),
|
||||
requesterIsAdmin: $user->isAdmin(),
|
||||
),
|
||||
);
|
||||
} catch (BadRequestException $exception) {
|
||||
return new JsonResponse(
|
||||
['error' => $exception->getMessage()], 400,
|
||||
);
|
||||
} catch (ForbiddenException $exception) {
|
||||
return new JsonResponse(
|
||||
['error' => $exception->getMessage()], 403,
|
||||
);
|
||||
}
|
||||
|
||||
return new JsonResponse(null, 204);
|
||||
}
|
||||
|
||||
public function delete(Request $request, int $id): JsonResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
|
|
@ -160,7 +237,8 @@ class PostController
|
|||
* authorDisplayName: string,
|
||||
* title: string,
|
||||
* body: string,
|
||||
* createdAt: string
|
||||
* createdAt: string,
|
||||
* featureSlot: ?int
|
||||
* }
|
||||
*/
|
||||
private function serialize(Post $post): array
|
||||
|
|
@ -176,6 +254,7 @@ class PostController
|
|||
'title' => $post->getTitle(),
|
||||
'body' => $post->getBody(),
|
||||
'createdAt' => $post->getCreatedAt()->format(DATE_ATOM),
|
||||
'featureSlot' => $post->getFeatureSlot(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Route::get('/me', [AuthController::class, 'me'])
|
|||
->middleware(AuthMiddleware::class);
|
||||
|
||||
Route::get('/posts', [PostController::class, 'recent']);
|
||||
Route::get('/posts/featured', [PostController::class, 'listFeatured']);
|
||||
Route::get('/posts/{id}', [PostController::class, 'show'])
|
||||
->whereNumber('id');
|
||||
Route::post('/posts', [PostController::class, 'create'])
|
||||
|
|
@ -26,6 +27,10 @@ Route::post('/posts', [PostController::class, 'create'])
|
|||
Route::delete('/posts/{id}', [PostController::class, 'delete'])
|
||||
->whereNumber('id')
|
||||
->middleware(AuthMiddleware::class);
|
||||
Route::post('/admin/posts/feature', [PostController::class, 'feature'])
|
||||
->middleware(AuthMiddleware::class);
|
||||
Route::post('/admin/posts/unfeature', [PostController::class, 'unfeature'])
|
||||
->middleware(AuthMiddleware::class);
|
||||
|
||||
Route::get(
|
||||
'/users/{displayName}/posts',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue