Skip to content

Add field-level and resource-level validation support #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions docs/crud_resource.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Defining Crud Resource

It's super easy to create a CrudResource for your model. To get started, we suggest creating a `CrudResources` directory
within your **app** folder and creating the resource classes there.

To start with, all you need is to create a class that extends the `\FigLab\CrudResource\CrudResource` abstract class and
define the `fields()` method.

Here's an example for the default `User` model that comes pre-installed with Laravel:

```php
<?php declare(strict_types=1);

namespace App\CrudResources;

use FigLab\CrudResource\CrudResource;
use App\Models\User;
use FigLab\CrudResource\Fields\Email;
use FigLab\CrudResource\Fields\Password;
use FigLab\CrudResource\Fields\Select;
use FigLab\CrudResource\Fields\Text;

class UserCrudResource extends CrudResource
{
public function fields(): array
{
return [
Text::make('Name')
->sortable(),

Email::make('Email'),

Password::make('Password')
->size(6)
->onlyOnForms(),

Password::make('Confirm Password', 'password_confirmation')
->size(6)
->onlyOnForms(),
];
}
}
```

Now, to use this CrudResource, you need to configure your controller accordingly. Here's the `UserController.php` that
shows how to do it:

```php
<?php declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Requests\User\UserStoreRequest;
use App\Http\Requests\User\UserUpdateRequest;
use App\CrudResources\User\UserCrudResource;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;

class UserCrudController extends CrudController
{
use ListOperation;
use CreateOperation;
use UpdateOperation;

private UserCrudResource $crudResource;

public function setup()
{
$this->crud->setModel(\App\Models\User::class);
$this->crud->setRoute(config('backpack.base.route_prefix') . '/users');
$this->crud->setEntityNameStrings('user', 'users');

$this->crudResource = new UserCrudResource($this->crud);
}

protected function setupListOperation(): void
{
$this->crudResource->buildList();
}

protected function setupCreateOperation(): void
{
$this->crud->setValidation(UserStoreRequest::class);

$this->crudResource->buildCreateForm();
}

protected function setupUpdateOperation(): void
{
$this->crud->setValidation(UserUpdateRequest::class);

$this->crudResource->buildUpdateForm();
}
}
```
4 changes: 4 additions & 0 deletions docs/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Documentation

- [Create a CrudResource](crud_resource.md)
- [Validation Rules](validation.md)
79 changes: 79 additions & 0 deletions docs/validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Validation

There are two ways in which you can add validation rules for your model.

### Field-level Validation Rules

You can specify the validation rules for each of the fields within your CrudResource. Here's an example:

```php
public function fields(): array
{
$id = $this->crud->getRequest()->input('id') ?? $this->crud->getRequest()->route('id');

return [
Text::make('Name')
->rules('required', 'min:5', 'max:255')
->sortable(),

Email::make('Email')
->rules('required')
->creationRules('unique:users,email')
->updateRules('unique:users,email,'.$id),

Password::make('Password')
->size(6)
->rules(['confirmed', 'min:8'])
->onlyOnForms(),

Password::make('Confirm Password', 'password_confirmation')
->size(6)
->creationRules('required')
->onlyOnForms(),
];
}
```

As shown in the example, there are three methods to use:

- **rules**: adds the validation rule for both create and update forms
- **creationRules**: adds the validation rule only for create form
- **updateRules**: adds the validation rule only for update form

You can pass an array of rules, or can specify the rules as individual parameters.

### Resource-level Validation Rules

In addition to the field-level validation, the validation rules/messages can also be added to the CrudResource itself. Example:

```php
/** @inheritDoc */
public function validationRules(): array
{
$id = $this->crud->getRequest()->get('id') ?? $this->crud->getRequest()->route('id');

$rules = [
'name' => 'required|min:5|max:255',
'role' => 'required',
];

$rules['email'] = $this->crud->getOperation() === 'create'
? 'required|unique:users,email'
: 'required|unique:users,email,'.$id;

$rules['password'] = $this->crud->getOperation() === 'create'
? 'required|confirmed'
: 'confirmed';

return $rules;
}

/** @inheritDoc */
public function validationMessages(): array
{
return [
'name.required' => 'You gotta give it a name, man.',
'name.min' => 'You came up short. Try more than 2 characters.',
];
}
```
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ composer require figlabhq/crud-resource-for-backpack

## Documentation

Coming soon...stay tuned 😅
Please see the [documentation](docs/readme.md) section for further details of the functionality.

## Change log

Expand Down
35 changes: 35 additions & 0 deletions src/CrudResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,24 @@ public function filters(): array
return [];
}

/** @return array<string, string | array<int, string>> */
public function validationRules(): array
{
return [];
}

/** @return array<string, string> */
public function validationMessages(): array
{
return [];
}

public function buildList(): void
{
foreach ($this->fields() as $field) {
$field->setRequest($this->crud->getRequest())
->setOperation($this->crud->getCurrentOperation());

if ($field->isShownOnIndex()) {
$this->crud->addColumn($field->columnDefinition());
}
Expand All @@ -39,18 +54,38 @@ public function buildList(): void
public function buildCreateForm(): void
{
foreach ($this->fields() as $field) {
$field->setRequest($this->crud->getRequest())
->setOperation($this->crud->getCurrentOperation());

if ($field->isShownOnCreation()) {
$this->crud->addField($field->fieldDefinition());
}
}

if (count($this->validationRules()) > 0) {
$this->crud->setValidation(
$this->validationRules(),
$this->validationMessages()
);
}
}

public function buildUpdateForm(): void
{
foreach ($this->fields() as $field) {
$field->setRequest($this->crud->getRequest())
->setOperation($this->crud->getCurrentOperation());

if ($field->isShownOnUpdate()) {
$this->crud->addField($field->fieldDefinition());
}
}

if (count($this->validationRules()) > 0) {
$this->crud->setValidation(
$this->validationRules(),
$this->validationMessages()
);
}
}
}
Loading