Standardised laravel validation to be array based

Converted from string-only-based validation.
Array based validation works nicer once you have validation classess or
advanced validation options.
This commit is contained in:
Dan Brown 2021-11-05 00:26:55 +00:00
parent 0ba8541370
commit 06b5009842
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
26 changed files with 106 additions and 109 deletions

View File

@ -95,17 +95,13 @@ class ApiDocsGenerator
} }
$rules = $class->getValdationRules()[$methodName] ?? []; $rules = $class->getValdationRules()[$methodName] ?? [];
foreach ($rules as $param => $ruleString) { return empty($rules) ? null : $rules;
$rules[$param] = explode('|', $ruleString);
}
return count($rules) > 0 ? $rules : null;
} }
/** /**
* Parse out the description text from a class method comment. * Parse out the description text from a class method comment.
*/ */
protected function parseDescriptionFromMethodComment(string $comment) protected function parseDescriptionFromMethodComment(string $comment): string
{ {
$matches = []; $matches = [];
preg_match_all('/^\s*?\*\s((?![@\s]).*?)$/m', $comment, $matches); preg_match_all('/^\s*?\*\s((?![@\s]).*?)$/m', $comment, $matches);

View File

@ -17,16 +17,16 @@ class AttachmentApiController extends ApiController
protected $rules = [ protected $rules = [
'create' => [ 'create' => [
'name' => 'required|min:1|max:255|string', 'name' => ['required', 'min:1', 'max:255', 'string'],
'uploaded_to' => 'required|integer|exists:pages,id', 'uploaded_to' => ['required', 'integer', 'exists:pages,id'],
'file' => 'required_without:link|file', 'file' => ['required_without:link', 'file'],
'link' => 'required_without:file|min:1|max:255|safe_url', 'link' => ['required_without:file', 'min:1', 'max:255', 'safe_url'],
], ],
'update' => [ 'update' => [
'name' => 'min:1|max:255|string', 'name' => ['min:1', 'max:255', 'string'],
'uploaded_to' => 'integer|exists:pages,id', 'uploaded_to' => ['integer', 'exists:pages,id'],
'file' => 'file', 'file' => ['file'],
'link' => 'min:1|max:255|safe_url', 'link' => ['min:1', 'max:255', 'safe_url'],
], ],
]; ];

View File

@ -13,14 +13,14 @@ class BookApiController extends ApiController
protected $rules = [ protected $rules = [
'create' => [ 'create' => [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'tags' => 'array', 'tags' => ['array'],
], ],
'update' => [ 'update' => [
'name' => 'string|min:1|max:255', 'name' => ['string', 'min:1', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'tags' => 'array', 'tags' => ['array'],
], ],
]; ];

View File

@ -18,14 +18,14 @@ class BookshelfApiController extends ApiController
protected $rules = [ protected $rules = [
'create' => [ 'create' => [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'books' => 'array', 'books' => ['array'],
], ],
'update' => [ 'update' => [
'name' => 'string|min:1|max:255', 'name' => ['string', 'min:1', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'books' => 'array', 'books' => ['array'],
], ],
]; ];

View File

@ -14,16 +14,16 @@ class ChapterApiController extends ApiController
protected $rules = [ protected $rules = [
'create' => [ 'create' => [
'book_id' => 'required|integer', 'book_id' => ['required', 'integer'],
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'tags' => 'array', 'tags' => ['array'],
], ],
'update' => [ 'update' => [
'book_id' => 'integer', 'book_id' => ['integer'],
'name' => 'string|min:1|max:255', 'name' => ['string', 'min:1', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'tags' => 'array', 'tags' => ['array'],
], ],
]; ];

View File

@ -16,20 +16,20 @@ class PageApiController extends ApiController
protected $rules = [ protected $rules = [
'create' => [ 'create' => [
'book_id' => 'required_without:chapter_id|integer', 'book_id' => ['required_without:chapter_id', 'integer'],
'chapter_id' => 'required_without:book_id|integer', 'chapter_id' => ['required_without:book_id', 'integer'],
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'html' => 'required_without:markdown|string', 'html' => ['required_without:markdown', 'string'],
'markdown' => 'required_without:html|string', 'markdown' => ['required_without:html', 'string'],
'tags' => 'array', 'tags' => ['array'],
], ],
'update' => [ 'update' => [
'book_id' => 'required|integer', 'book_id' => ['required', 'integer'],
'chapter_id' => 'required|integer', 'chapter_id' => ['required', 'integer'],
'name' => 'string|min:1|max:255', 'name' => ['string', 'min:1', 'max:255'],
'html' => 'string', 'html' => ['string'],
'markdown' => 'string', 'markdown' => ['string'],
'tags' => 'array', 'tags' => ['array'],
], ],
]; ];

View File

@ -36,8 +36,8 @@ class AttachmentController extends Controller
public function upload(Request $request) public function upload(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'uploaded_to' => 'required|integer|exists:pages,id', 'uploaded_to' => ['required', 'integer', 'exists:pages,id'],
'file' => 'required|file', 'file' => ['required', 'file'],
]); ]);
$pageId = $request->get('uploaded_to'); $pageId = $request->get('uploaded_to');
@ -65,7 +65,7 @@ class AttachmentController extends Controller
public function uploadUpdate(Request $request, $attachmentId) public function uploadUpdate(Request $request, $attachmentId)
{ {
$this->validate($request, [ $this->validate($request, [
'file' => 'required|file', 'file' => ['required', 'file'],
]); ]);
/** @var Attachment $attachment */ /** @var Attachment $attachment */
@ -111,8 +111,8 @@ class AttachmentController extends Controller
try { try {
$this->validate($request, [ $this->validate($request, [
'attachment_edit_name' => 'required|string|min:1|max:255', 'attachment_edit_name' => ['required', 'string', 'min:1', 'max:255'],
'attachment_edit_url' => 'string|min:1|max:255|safe_url', 'attachment_edit_url' => ['string', 'min:1', 'max:255', 'safe_url'],
]); ]);
} catch (ValidationException $exception) { } catch (ValidationException $exception) {
return response()->view('attachments.manager-edit-form', array_merge($request->only(['attachment_edit_name', 'attachment_edit_url']), [ return response()->view('attachments.manager-edit-form', array_merge($request->only(['attachment_edit_name', 'attachment_edit_url']), [
@ -146,9 +146,9 @@ class AttachmentController extends Controller
try { try {
$this->validate($request, [ $this->validate($request, [
'attachment_link_uploaded_to' => 'required|integer|exists:pages,id', 'attachment_link_uploaded_to' => ['required', 'integer', 'exists:pages,id'],
'attachment_link_name' => 'required|string|min:1|max:255', 'attachment_link_name' => ['required', 'string', 'min:1', 'max:255'],
'attachment_link_url' => 'required|string|min:1|max:255|safe_url', 'attachment_link_url' => ['required', 'string', 'min:1', 'max:255', 'safe_url'],
]); ]);
} catch (ValidationException $exception) { } catch (ValidationException $exception) {
return response()->view('attachments.manager-link-form', array_merge($request->only(['attachment_link_name', 'attachment_link_url']), [ return response()->view('attachments.manager-link-form', array_merge($request->only(['attachment_link_name', 'attachment_link_url']), [
@ -195,7 +195,7 @@ class AttachmentController extends Controller
public function sortForPage(Request $request, int $pageId) public function sortForPage(Request $request, int $pageId)
{ {
$this->validate($request, [ $this->validate($request, [
'order' => 'required|array', 'order' => ['required', 'array'],
]); ]);
$page = $this->pageRepo->getById($pageId); $page = $this->pageRepo->getById($pageId);
$this->checkOwnablePermission('page-update', $page); $this->checkOwnablePermission('page-update', $page);

View File

@ -107,7 +107,7 @@ class ConfirmEmailController extends Controller
public function resend(Request $request) public function resend(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'email' => 'required|email|exists:users,email', 'email' => ['required', 'email', 'exists:users,email'],
]); ]);
$user = $this->userRepo->getByEmail($request->get('email')); $user = $this->userRepo->getByEmail($request->get('email'));

View File

@ -43,7 +43,9 @@ class ForgotPasswordController extends Controller
*/ */
public function sendResetLinkEmail(Request $request) public function sendResetLinkEmail(Request $request)
{ {
$this->validate($request, ['email' => 'required|email']); $this->validate($request, [
'email' => ['required', 'email']
]);
// We will send the password reset link to this user. Once we have attempted // We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we // to send the link, we will examine the response then see the message we

View File

@ -176,16 +176,16 @@ class LoginController extends Controller
*/ */
protected function validateLogin(Request $request) protected function validateLogin(Request $request)
{ {
$rules = ['password' => 'required|string']; $rules = ['password' => ['required', 'string']];
$authMethod = config('auth.method'); $authMethod = config('auth.method');
if ($authMethod === 'standard') { if ($authMethod === 'standard') {
$rules['email'] = 'required|email'; $rules['email'] = ['required', 'email'];
} }
if ($authMethod === 'ldap') { if ($authMethod === 'ldap') {
$rules['username'] = 'required|string'; $rules['username'] = ['required', 'string'];
$rules['email'] = 'email'; $rules['email'] = ['email'];
} }
$request->validate($rules); $request->validate($rules);

View File

@ -73,8 +73,7 @@ class MfaBackupCodesController extends Controller
$this->validate($request, [ $this->validate($request, [
'code' => [ 'code' => [
'required', 'required', 'max:12', 'min:8',
'max:12', 'min:8',
function ($attribute, $value, $fail) use ($codeService, $codes) { function ($attribute, $value, $fail) use ($codeService, $codes) {
if (!$codeService->inputCodeExistsInSet($value, $codes)) { if (!$codeService->inputCodeExistsInSet($value, $codes)) {
$fail(trans('validation.backup_codes')); $fail(trans('validation.backup_codes'));

View File

@ -68,9 +68,9 @@ class RegisterController extends Controller
protected function validator(array $data) protected function validator(array $data)
{ {
return Validator::make($data, [ return Validator::make($data, [
'name' => 'required|min:2|max:255', 'name' => ['required', 'min:2', 'max:255'],
'email' => 'required|email|max:255|unique:users', 'email' => ['required', 'email', 'max:255', 'unique:users'],
'password' => 'required|min:8', 'password' => ['required', 'min:8'],
]); ]);
} }

View File

@ -58,7 +58,7 @@ class UserInviteController extends Controller
public function setPassword(Request $request, string $token) public function setPassword(Request $request, string $token)
{ {
$this->validate($request, [ $this->validate($request, [
'password' => 'required|min:8', 'password' => ['required', 'min:8'],
]); ]);
try { try {

View File

@ -85,9 +85,9 @@ class BookController extends Controller
{ {
$this->checkPermission('book-create-all'); $this->checkPermission('book-create-all');
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'image' => 'nullable|' . $this->getImageValidationRules(), 'image' => array_merge(['nullable'], $this->getImageValidationRules()),
]); ]);
$bookshelf = null; $bookshelf = null;
@ -156,9 +156,9 @@ class BookController extends Controller
$book = $this->bookRepo->getBySlug($slug); $book = $this->bookRepo->getBySlug($slug);
$this->checkOwnablePermission('book-update', $book); $this->checkOwnablePermission('book-update', $book);
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'image' => 'nullable|' . $this->getImageValidationRules(), 'image' => array_merge(['nullable'], $this->getImageValidationRules()),
]); ]);
$book = $this->bookRepo->update($book, $request->all()); $book = $this->bookRepo->update($book, $request->all());

View File

@ -84,9 +84,9 @@ class BookshelfController extends Controller
{ {
$this->checkPermission('bookshelf-create-all'); $this->checkPermission('bookshelf-create-all');
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'image' => 'nullable|' . $this->getImageValidationRules(), 'image' => array_merge(['nullable'], $this->getImageValidationRules()),
]); ]);
$bookIds = explode(',', $request->get('books', '')); $bookIds = explode(',', $request->get('books', ''));
@ -161,9 +161,9 @@ class BookshelfController extends Controller
$shelf = $this->bookshelfRepo->getBySlug($slug); $shelf = $this->bookshelfRepo->getBySlug($slug);
$this->checkOwnablePermission('bookshelf-update', $shelf); $this->checkOwnablePermission('bookshelf-update', $shelf);
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
'description' => 'string|max:1000', 'description' => ['string', 'max:1000'],
'image' => 'nullable|' . $this->getImageValidationRules(), 'image' => array_merge(['nullable'], $this->getImageValidationRules()),
]); ]);
$bookIds = explode(',', $request->get('books', '')); $bookIds = explode(',', $request->get('books', ''));

View File

@ -47,7 +47,7 @@ class ChapterController extends Controller
public function store(Request $request, string $bookSlug) public function store(Request $request, string $bookSlug)
{ {
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
]); ]);
$book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail(); $book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();

View File

@ -24,8 +24,8 @@ class CommentController extends Controller
public function savePageComment(Request $request, int $pageId) public function savePageComment(Request $request, int $pageId)
{ {
$this->validate($request, [ $this->validate($request, [
'text' => 'required|string', 'text' => ['required', 'string'],
'parent_id' => 'nullable|integer', 'parent_id' => ['nullable', 'integer'],
]); ]);
$page = Page::visible()->find($pageId); $page = Page::visible()->find($pageId);
@ -53,7 +53,7 @@ class CommentController extends Controller
public function update(Request $request, int $commentId) public function update(Request $request, int $commentId)
{ {
$this->validate($request, [ $this->validate($request, [
'text' => 'required|string', 'text' => ['required', 'string'],
]); ]);
$comment = $this->commentRepo->getById($commentId); $comment = $this->commentRepo->getById($commentId);

View File

@ -175,8 +175,8 @@ abstract class Controller extends BaseController
/** /**
* Get the validation rules for image files. * Get the validation rules for image files.
*/ */
protected function getImageValidationRules(): string protected function getImageValidationRules(): array
{ {
return 'image_extension|mimes:jpeg,png,gif,webp'; return ['image_extension', 'mimes:jpeg,png,gif,webp'];
} }
} }

View File

@ -69,8 +69,8 @@ class FavouriteController extends Controller
protected function getValidatedModelFromRequest(Request $request): Favouritable protected function getValidatedModelFromRequest(Request $request): Favouritable
{ {
$modelInfo = $this->validate($request, [ $modelInfo = $this->validate($request, [
'type' => 'required|string', 'type' => ['required', 'string'],
'id' => 'required|integer', 'id' => ['required', 'integer'],
]); ]);
if (!class_exists($modelInfo['type'])) { if (!class_exists($modelInfo['type'])) {

View File

@ -44,8 +44,8 @@ class DrawioImageController extends Controller
public function create(Request $request) public function create(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'image' => 'required|string', 'image' => ['required', 'string'],
'uploaded_to' => 'required|integer', 'uploaded_to' => ['required', 'integer'],
]); ]);
$this->checkPermission('image-create-all'); $this->checkPermission('image-create-all');

View File

@ -51,7 +51,7 @@ class ImageController extends Controller
public function update(Request $request, string $id) public function update(Request $request, string $id)
{ {
$this->validate($request, [ $this->validate($request, [
'name' => 'required|min:2|string', 'name' => ['required', 'min:2', 'string'],
]); ]);
$image = $this->imageRepo->getById($id); $image = $this->imageRepo->getById($id);

View File

@ -60,7 +60,7 @@ class PageController extends Controller
public function createAsGuest(Request $request, string $bookSlug, string $chapterSlug = null) public function createAsGuest(Request $request, string $bookSlug, string $chapterSlug = null)
{ {
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
]); ]);
$parent = $this->pageRepo->getParentFromSlugs($bookSlug, $chapterSlug); $parent = $this->pageRepo->getParentFromSlugs($bookSlug, $chapterSlug);
@ -107,7 +107,7 @@ class PageController extends Controller
public function store(Request $request, string $bookSlug, int $pageId) public function store(Request $request, string $bookSlug, int $pageId)
{ {
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
]); ]);
$draftPage = $this->pageRepo->getById($pageId); $draftPage = $this->pageRepo->getById($pageId);
$this->checkOwnablePermission('page-create', $draftPage->getParent()); $this->checkOwnablePermission('page-create', $draftPage->getParent());
@ -234,7 +234,7 @@ class PageController extends Controller
public function update(Request $request, string $bookSlug, string $pageSlug) public function update(Request $request, string $bookSlug, string $pageSlug)
{ {
$this->validate($request, [ $this->validate($request, [
'name' => 'required|string|max:255', 'name' => ['required', 'string', 'max:255'],
]); ]);
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
$this->checkOwnablePermission('page-update', $page); $this->checkOwnablePermission('page-update', $page);

View File

@ -48,7 +48,7 @@ class RoleController extends Controller
{ {
$this->checkPermission('user-roles-manage'); $this->checkPermission('user-roles-manage');
$this->validate($request, [ $this->validate($request, [
'display_name' => 'required|min:3|max:180', 'display_name' => ['required', 'min:3', 'max:180'],
'description' => 'max:180', 'description' => 'max:180',
]); ]);
@ -83,7 +83,7 @@ class RoleController extends Controller
{ {
$this->checkPermission('user-roles-manage'); $this->checkPermission('user-roles-manage');
$this->validate($request, [ $this->validate($request, [
'display_name' => 'required|min:3|max:180', 'display_name' => ['required', 'min:3', 'max:180'],
'description' => 'max:180', 'description' => 'max:180',
]); ]);

View File

@ -44,7 +44,7 @@ class SettingController extends Controller
$this->preventAccessInDemoMode(); $this->preventAccessInDemoMode();
$this->checkPermission('settings-manage'); $this->checkPermission('settings-manage');
$this->validate($request, [ $this->validate($request, [
'app_logo' => 'nullable|' . $this->getImageValidationRules(), 'app_logo' => array_merge(['nullable'], $this->getImageValidationRules()),
]); ]);
// Cycles through posted settings and update them // Cycles through posted settings and update them

View File

@ -36,8 +36,8 @@ class UserApiTokenController extends Controller
$this->checkPermissionOrCurrentUser('users-manage', $userId); $this->checkPermissionOrCurrentUser('users-manage', $userId);
$this->validate($request, [ $this->validate($request, [
'name' => 'required|max:250', 'name' => ['required', 'max:250'],
'expires_at' => 'date_format:Y-m-d', 'expires_at' => ['date_format:Y-m-d'],
]); ]);
$user = User::query()->findOrFail($userId); $user = User::query()->findOrFail($userId);
@ -86,8 +86,8 @@ class UserApiTokenController extends Controller
public function update(Request $request, int $userId, int $tokenId) public function update(Request $request, int $userId, int $tokenId)
{ {
$this->validate($request, [ $this->validate($request, [
'name' => 'required|max:250', 'name' => ['required', 'max:250'],
'expires_at' => 'date_format:Y-m-d', 'expires_at' => ['date_format:Y-m-d'],
]); ]);
[$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId); [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);

View File

@ -74,18 +74,18 @@ class UserController extends Controller
{ {
$this->checkPermission('users-manage'); $this->checkPermission('users-manage');
$validationRules = [ $validationRules = [
'name' => 'required', 'name' => ['required'],
'email' => 'required|email|unique:users,email', 'email' => ['required', 'email', 'unique:users,email'],
]; ];
$authMethod = config('auth.method'); $authMethod = config('auth.method');
$sendInvite = ($request->get('send_invite', 'false') === 'true'); $sendInvite = ($request->get('send_invite', 'false') === 'true');
if ($authMethod === 'standard' && !$sendInvite) { if ($authMethod === 'standard' && !$sendInvite) {
$validationRules['password'] = 'required|min:6'; $validationRules['password'] = ['required', 'min:6'];
$validationRules['password-confirm'] = 'required|same:password'; $validationRules['password-confirm'] = ['required', 'same:password'];
} elseif ($authMethod === 'ldap' || $authMethod === 'saml2' || $authMethod === 'openid') { } elseif ($authMethod === 'ldap' || $authMethod === 'saml2' || $authMethod === 'openid') {
$validationRules['external_auth_id'] = 'required'; $validationRules['external_auth_id'] = ['required'];
} }
$this->validate($request, $validationRules); $this->validate($request, $validationRules);
@ -156,11 +156,11 @@ class UserController extends Controller
$this->validate($request, [ $this->validate($request, [
'name' => 'min:2', 'name' => 'min:2',
'email' => 'min:2|email|unique:users,email,' . $id, 'email' => ['min:2', 'email', 'unique:users,email,' . $id],
'password' => 'min:6|required_with:password_confirm', 'password' => ['min:6', 'required_with:password_confirm'],
'password-confirm' => 'same:password|required_with:password', 'password-confirm' => ['same:password', 'required_with:password'],
'setting' => 'array', 'setting' => 'array',
'profile_image' => 'nullable|' . $this->getImageValidationRules(), 'profile_image' => array_merge(['nullable'], $this->getImageValidationRules()),
]); ]);
$user = $this->userRepo->getById($id); $user = $this->userRepo->getById($id);