Hi,
I've switched to the new validations. One thing I had struggle with is the confirmed validation rule of Laravel. If I understood your docs correct, using this validation is not possible without conditionally adding a rule. My tests always failed, stating that the confirmation is not present. I got it working after a while with a conditional added rule.
My solution for confirming the password looks like this. The adding of the confirmed rule could be moved in a method to reduce code duplication, but for demonstration I did not.
use CloudCreativity\LaravelJsonApi\Validation\AbstractValidators;
use CloudCreativity\LaravelJsonApi\Contracts\Validation\ValidatorInterface;
use Illuminate\Support\Arr;
class Validators extends AbstractValidators {
protected function rules($record = null): array {
return [
'password' => [!is_null($record) ? 'sometimes' : '', 'required'],
];
}
public function create(array $document): ValidatorInterface {
$validator = parent::create($document);
$validator->sometimes('password_confirmation', 'required|same:password', function () use ($document) {
return Arr::has($document, 'data.attributes.password');
});
return $validator;
}
public function update($record, array $document): ValidatorInterface {
$validator = parent::update($record, $document);
$validator->sometimes('password_confirmation', 'required|same:password', function () use ($document) {
return Arr::has($document, 'data.attributes.password');
});
return $validator;
}
}
Is this the correct approach or is there a better way? If this is a good solution, maybe think of adding a mechanism to make this easier? Maybe it's worth adding this case to the validations docs. What do you think?
Best regards, Jannis
Is the JSON API field name for your password confirmation password_confirmation or password-confirmation?
It's password_confirmation.
Hmmm. Ok. I'll have a look into this because I would have thought the confirmation rule should work fine (but haven't tried it myself)...
@lindyhopchris any news on this?
@jannis-a sorry, haven't had time to look into it yet. Will do soon.
So just looked into this. The conditional rules stuff isn't relevant here - you just need to use the confirmed rule. I.e.
<?php
namespace DummyApp\JsonApi\Users;
use CloudCreativity\LaravelJsonApi\Validation\AbstractValidators;
class Validators extends AbstractValidators
{
// ...
protected function rules($record = null): array
{
return [
'name' => 'required|string',
'password' => "required|confirmed",
];
}
}
Laravel will then expect there to be a password_confirmation field in the data. This works if you're using underscores for your field names.
Unfortunately Laravel does not allow the confirmation field to be customised. Therefore if you're using dash-case it won't pick up on password-confirmation and it will fail.
I'll have to write something to iterate over every single key and change it if it ends in -confirmation before passing into the Laravel validator :-(
Actually if you're not using underscores, you can solve it like this:
<?php
namespace DummyApp\JsonApi\Users;
use CloudCreativity\LaravelJsonApi\Validation\AbstractValidators;
class Validators extends AbstractValidators
{
// ...
protected function rules($record = null): array
{
return [
'name' => 'required|string',
'password' => "required|string",
'password-confirmation' => "required_with:password|same:password",
];
}
}
I'll add something to the docs.
If you're using password-confirmation, this should do it:
namespace App\JsonApi\Users;
use CloudCreativity\LaravelJsonApi\Contracts\Validation\ValidatorInterface;
use CloudCreativity\LaravelJsonApi\Validation\AbstractValidators;
class Validators extends AbstractValidators
{
// ...
public function update($record, array $document): ValidatorInterface
{
$validator = parent::update($record, $document);
$validator->sometimes('password-confirmation', 'required_with:password|same:password', function ($input) {
return isset($input['password']);
});
return $validator;
}
protected function rules($record = null): array
{
$rules = [
'name' => 'required|string',
'password' => [
$record ? 'filled' : 'required',
'string',
],
];
if (!$record) {
$rules['password-confirmation'] = 'required_with:password|same:password';
}
return $rules;
}
}