Skip to content

Commit

Permalink
Allow to specify attribute name in type class
Browse files Browse the repository at this point in the history
  • Loading branch information
azzumed committed Aug 19, 2024
1 parent 16a842a commit b7cdb9e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 0 deletions.
27 changes: 27 additions & 0 deletions docs/validation/working-with-the-validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,33 @@ class SongData extends Data
}
```

### Defining attribute in type

If you want to define attribute name in the type itself, you can implement the `HasValidationAttributeName` interface:

```php
class SongData extends Data
{
public function __construct(
public Title $title,
) {
}
}

class Title implements HasValidationAttributeName
{
public function __construct(
public string $value,
) {
}

public static function validationAttributeName(): string
{
return 'Song title';
}
}
```

## Overwriting other validation functionality

Next to overwriting the validator, attributes and messages it is also possible to overwrite the following functionality.
Expand Down
8 changes: 8 additions & 0 deletions src/Contracts/HasValidationAttributeName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Spatie\LaravelData\Contracts;

interface HasValidationAttributeName
{
public static function validationAttributeName(): string;
}
10 changes: 10 additions & 0 deletions src/Resolvers/DataValidationMessagesAndAttributesResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace Spatie\LaravelData\Resolvers;

use Illuminate\Support\Arr;
use Spatie\LaravelData\Contracts\HasValidationAttributeName;
use Spatie\LaravelData\Support\DataConfig;
use Spatie\LaravelData\Support\Types\NamedType;
use Spatie\LaravelData\Support\Validation\ValidationPath;

class DataValidationMessagesAndAttributesResolver
Expand Down Expand Up @@ -62,6 +64,14 @@ public function execute(

continue;
}

if ($dataProperty->type->type instanceof NamedType) {
$typeClass = $dataProperty->type->type->name;

if (is_a($typeClass, HasValidationAttributeName::class, true)) {
$attributes[$propertyPath->get()] = app()->call([$typeClass, 'validationAttributeName']);
}
}
}

if (method_exists($class, 'messages')) {
Expand Down
24 changes: 24 additions & 0 deletions tests/ValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use Spatie\LaravelData\Attributes\Validation\StringType;
use Spatie\LaravelData\Attributes\Validation\Unique;
use Spatie\LaravelData\Attributes\WithoutValidation;
use Spatie\LaravelData\Contracts\HasValidationAttributeName;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\DataCollection;
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
Expand Down Expand Up @@ -1969,6 +1970,29 @@ public static function attributes(FakeInjectable $injectable): array
);
});

it('can resolve validation attributes from type ', function () {
class Address implements HasValidationAttributeName {
public function __construct(
public string $value,
) {
}

public static function validationAttributeName(): string
{
return 'Home address';
}
}

$data = new class () extends Data {
public Address $address;
};

DataValidationAsserter::for($data)
->assertAttributes([
'address' => 'Home address',
]);
});

it('can manually set the redirect url', function () {
$data = new class () extends Data {
public string $name;
Expand Down

0 comments on commit b7cdb9e

Please sign in to comment.