De-duplicate controller boilerplate: owned-project lookup, reorder validation
requireOwnedProjectId() was copy-pasted identically in CardController and CardStatusController; ProjectController's own requireOwnedProject() was the same lookup, just returning the full row instead of the id. New abstract ProjectScopedController (extends Controller) holds one copy of both, and all three controllers now extend it instead of Controller directly, forwarding their ProjectRepository to its constructor. Separately, CardController::reorder() (card_ids) and CardStatusController::reorder() (status_ids) each had the same inline 'must be an array of ids, no duplicates' check. Both now call a new Validator::intIdArray(), which does the same shape check once. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exception\ApiException;
|
||||
use App\Repository\ProjectRepository;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* Shared helper for controllers whose routes are nested under
|
||||
* /projects/{projectId}: looking up the project named in the route, 404-ing
|
||||
* if it's missing or not owned by the caller.
|
||||
*/
|
||||
abstract class ProjectScopedController extends Controller
|
||||
{
|
||||
public function __construct(protected readonly ProjectRepository $projects)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The project named in the route, or 404 if it is missing or not owned
|
||||
* by the authenticated user.
|
||||
*
|
||||
* @param array<string, string> $args
|
||||
* @return array{id: int, owner_id: int, title: string, description: string, card_count: int, completed_count: int, created_at: string, updated_at: string}
|
||||
*/
|
||||
protected function requireOwnedProject(Request $request, array $args): array
|
||||
{
|
||||
$project = $this->projects->findOwnedBy((int) $args['projectId'], $this->user($request)['id']);
|
||||
|
||||
if ($project === null) {
|
||||
throw new ApiException('Project not found.', 404);
|
||||
}
|
||||
|
||||
return $project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $args
|
||||
*/
|
||||
protected function requireOwnedProjectId(Request $request, array $args): int
|
||||
{
|
||||
return $this->requireOwnedProject($request, $args)['id'];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user