Skip to content
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

Filters refactoring #663

Merged
merged 30 commits into from
May 17, 2022
Merged

Filters refactoring #663

merged 30 commits into from
May 17, 2022

Conversation

butschster
Copy link
Member

@butschster butschster commented Apr 19, 2022

Q A
Bugfix?
Breaks BC? ✔️
New feature? ✔️
  • Validation interceptor
  • Authorization interceptor
  • Mapping input data via attributes
  • Unit tests
  • Docs

Example

Controller

class UserController
{
    public function createUser(CreateUser $filter): array
    {
           $user = new User($filter->username, $filter->firstName, $filter->lastName);
           $user->setUtmData($filter->urm->id, $filter->utm->source);

           foreach($filter->tags as $tag) {
                $user->addTag($tag->role);
           }

           $this->em->persist($user);
    }
}

Filters

<?php

declare(strict_types=1);

namespace App\Filter;

use Spiral\Filters\Attribute\Input;
use Spiral\Filters\Attribute\NestedArray;
use Spiral\Filters\Attribute\Setter;
use Spiral\Filters\Attribute\NestedFilter;
use Spiral\Validation\Symfony\Filter as SymfonyFilter;
use Symfony\Component\Validator\Constraints as Assert;

class CreateUser extends SymfonyFilter
{
    #[Assert\NotBlank]
    #[Assert\Length(['min' => 30])]
    #[Input\Post]
    public string $username;

    #[Input\Post('first_name')]
    public string $firstName;

    #[Input\Post('last_name')]
    public string $lastName;

    #[NestedArray(class: UserTagsFilter::class, input: new Input\Post('tags'))]
    public array $tags = [];

    #[NestedFilter(class: UtmFilter::class)]
    public UtmFilter $utm;

    #[Input\Post]
    #[Setter(filter: 'md5')]
    public string $password;
}
<?php

declare(strict_types=1);

namespace App\Filter;

use App\Bootloader\Laravel\FilterDefinition;
use Spiral\Filters\Filter;
use Spiral\Filters\Attribute\Input;
use Spiral\Filters\FilterDefinitionInterface;

class UtmFilter extends Filter
{
    #[Input\Post('utm_id')]
    public ?string $id = null;

    #[Input\Post('utm_source')]
    public string $source;

    #[Input\Post('utm_medium')]
    public string $medium;

    #[Input\Post('utm_campaign')]
    public ?string $campaign = null;

    #[Input\Post('utm_term')]
    public ?string $term = null;

    #[Input\Post('utm_content')]
    public ?string $content = null;

    public function filterDefinition(): FilterDefinitionInterface
    {
        return new FilterDefinition([
            'id' => ['required', 'min:5', 'max:10'],
            'source' => ['required', 'min:5', 'max:10'],
        ]);
    }
}
<?php

declare(strict_types=1);

namespace App\Filter;

use Spiral\Filters\Attribute\Input;
use Spiral\Validation\Symfony\Filter as SymfonyFilter;
use Symfony\Component\Validator\Constraints as Assert;

class UserTagsFilter extends SymfonyFilter
{
    #[Assert\NotBlank]
    #[Assert\Length(['min' => 30])]
    #[Input\Post]
    public string $name;

    #[Assert\NotBlank]
    #[Assert\Length(['min' => 3])]
    #[Input\Post]
    public string $role;
}
        $http = $this->fakeHttp();
        $http
            ->post(
                uri: '/createUser.html',
                data: [
                    'username' => 'john_smith',
                    'first_name' => 'John',
                    'last_name' => 'Smith',
                    'password' => 'secret',
                    'utm_id' => '34wmrn_34n25nj3_4k23bn_4dkj2n34',
                    'utm_source' => 'google',
                    'utm_medium' => 'cpc',
                    'utm_term' => 'search',
                    'tags' => [
                        'first' => [
                            'name' => 'Admin',
                            'role' => 'admin',
                        ],
                        'second' => [
                            'name' => 'Manager',
                            'role' => 'manager',
                        ],
                    ],
                ],
                files: [
                    'avatar' => $http->getFileFactory()->createImage('avatar.jpg'),
                ]
            );

@butschster butschster self-assigned this Apr 19, 2022
@butschster butschster added this to the 3.0 milestone Apr 19, 2022
@butschster butschster linked an issue Apr 19, 2022 that may be closed by this pull request
@butschster butschster requested a review from roxblnfk May 13, 2022 09:28
@butschster butschster requested review from msmakouz and roxblnfk and removed request for roxblnfk May 13, 2022 09:28
src/Filters/composer.json Show resolved Hide resolved
src/Filters/src/Attribute/Input/IsJsonExpected.php Outdated Show resolved Hide resolved
src/Validation/src/ValidationProviderInterface.php Outdated Show resolved Hide resolved
src/Http/src/Request/InputManager.php Outdated Show resolved Hide resolved
src/Filters/src/Attribute/Input/Route.php Outdated Show resolved Hide resolved
src/Filters/src/Attribute/Input/Server.php Outdated Show resolved Hide resolved
src/Filters/src/Attribute/NestedArray.php Show resolved Hide resolved
src/Filters/src/Attribute/NestedFilter.php Show resolved Hide resolved
src/Filters/src/Attribute/Setter.php Show resolved Hide resolved
@codecov
Copy link

codecov bot commented May 17, 2022

Codecov Report

Merging #663 (3d92f57) into 3.0 (b9522d0) will decrease coverage by 0.69%.
The diff coverage is 91.22%.

@@             Coverage Diff              @@
##                3.0     #663      +/-   ##
============================================
- Coverage     82.37%   81.67%   -0.70%     
+ Complexity     5454     5213     -241     
============================================
  Files           621      619       -2     
  Lines         13538    13078     -460     
============================================
- Hits          11152    10682     -470     
- Misses         2386     2396      +10     
Impacted Files Coverage Δ
src/Filters/src/ErrorMapper.php 47.05% <0.00%> (-52.95%) ⬇️
src/Http/src/Request/InputManager.php 91.48% <0.00%> (-8.52%) ⬇️
src/Validation/src/ValidationProvider.php 0.00% <0.00%> (-97.37%) ⬇️
src/Filters/src/Filter.php 50.00% <50.00%> (-44.83%) ⬇️
src/Filters/src/FilterProvider.php 82.60% <80.95%> (-15.61%) ⬇️
src/Filters/src/Schema/AttributeMapper.php 95.23% <95.23%> (ø)
src/Filters/src/Schema/InputMapper.php 96.77% <96.77%> (ø)
src/Filters/src/Attribute/Input/AbstractInput.php 100.00% <100.00%> (ø)
src/Filters/src/Attribute/Input/Attribute.php 100.00% <100.00%> (ø)
src/Filters/src/Attribute/Input/BearerToken.php 100.00% <100.00%> (ø)
... and 41 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b9522d0...3d92f57. Read the comment docs.

@butschster butschster merged commit 64ea917 into 3.0 May 17, 2022
@butschster butschster deleted the feature/379-filters branch June 23, 2022 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Better validation DSL
3 participants