Laravel style FormRequests for Symfony; inspired by adamsafr/form-request-bundle

Overview

Somnambulist Form Request Bundle

GitHub Actions Build Status Issues License PHP Version Current Version

An implementation of form requests from Laravel for Symfony based on the original work by Adam Sapraliev.

Requirements

  • PHP 8.0+
  • symfony/framework-bundle

Installation

Install using composer, or checkout / pull the files from github.com.

  • composer require somnambulist/form-request-bundle

Usage

Add the SomnambulistFormRequestBundle to your bundles.php list and add a config file in packages if you wish to configure the bundle. The following options can be set:

somnambulist_form_request:
    subscribers:
        authorization: true
        form_validation: true

authorization registers an event subscriber that will convert AccessDeniedExceptions to a JSON response. form_validation registers an event subscriber that will convert FormValidationException to a JSON response including the fields that failed validation and the rules and message that failed.

Note: the subscribers are enabled by default.

Custom Rules

This package includes overrides for the following rules:

  • required - validates a field is required supporting Symfony UploadedFile files
  • uploaded_file - validates an uploaded file supporting Symfony UploadedFile files
  • mimes - validates an uploaded file mime-type is one of the given extensions

Property Pass-Through

The following ParameterBags can be accessed via property accessors or method calls:

  • attributes
  • cookies
  • files
  • headers
  • query
  • request
  • server

In addition, the following properties are also available:

  • content
  • session

Making a Form Request

To make a form request, extend the base Somnambulist\Bundles\FormRequestBundle\Http\FormRequest class and override the rules() method to add your own validation rules. The rules method has access to the current request via the source property so rules can be constructed using request information.

The validation rules use somnambulist/validation instead of Symfony's validation component to allow for easier setup and extension.

For example: to make a form request specifically for validating the data to make a new user you could create the following:

<?php
use Somnambulist\Bundles\FormRequestBundle\Http\FormRequest;

class NewUserFormRequest extends FormRequest
{
    public function rules() : array
    {
        return [
            'name'     => 'required|min:8|max:100',
            'email'    => 'required|min:4|max:255|email',
            'password' => 'required|min:8|max:100',
        ];
    }
}

Validated data is stored in the data property and is accessible directly from the controller. From version 1.5.0 this is a ValidatedDataBag, previously it was a ParameterBag. The data bag supports dot notation access to keys (with the same restrictions as the main FormRequest) along with nullOrValue and several other methods for keys, values, and filtering by callback.

Alternatively: the original request data can be accessed via property pass-through or by calling source() to get the request object.

Using the Form Request

In your controller, instead of type-hinting the standard request, type-hint your form request. If validation succeeds, then the data in the request will be suitable for the controller to use.

For example:

<?php
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class CreateUserController extends AbstractController
{
    public function __invoke(NewUserFormRequest $form)
    {
        // handle request
        $form->data()->get('name');
    }
}

FormRequests support dot notation access to get to nested values. This can be used for single values, to check for deeply nested values easily or to extract a set of values into a value object or set.

For example: to get a single value: $form->get('user.address.line_1') would get line_1 from a user array that contains an address array.

The behaviour of dot notation has several edge cases:

  • * operator is not supported at this time,
  • only will return a flattened ParameterBag with the dot notation keys
  • without will return a ParameterBag with the original data without the specified keys

Additionally:

When using dot notation with only the result will be similar to nullOrValue with subNull as false however it may contain values from the request, query, or files. nullOrValue will only work with a single data source. If you require fine control use nullOrValue.

When using dot notation with without the result will contain data from request, query, and files. As a ParameterBag is returned, there are no dot accessors.

Optionally:

If you make use of api-bundle and document query arguments that should not be treated as part of the validated data (e.g. page/per_page etc); these can be excluded from the validated data by overriding the $ignore property with the set of key names that should be excluded from the validated data.

Authorizing a Form Request

Form requests can have custom authorization checks; however this feature requires that Symfony Security has been implemented as the security service is required.

To add custom auth checks override the authorize() method and add the necessary checks.

The authorize method receives the current Security service that has access to the current user and the isGranted() method.

For example, to require new users can only be made by an Admin user:

use Somnambulist\Bundles\FormRequestBundle\Http\FormRequest;
use Symfony\Component\Security\Core\Security;

class NewUserFormRequest extends FormRequest
{
    public function authorize(Security $security) : bool
    {
        return $security->isGranted('ROLE_ADMIN');
    }

    public function rules() : array
    {
        return [
            'name'     => 'required|min:8|max:100',
            'email'    => 'required|min:4|max:255|email',
            'password' => 'required|min:8|max:100',
        ];
    }
}

Adding Validator Rules

Custom validators can be added by creating a new Rule that extends Somnambulist\Components\Validation\Rule, implementing the logic for validation (and any custom messages) and then creating a new service. Rules will be automatically assigned to the validator using the class name without namespace converted to snake_case. Alternatively individual rules can be tagged with somnambulist.form_request_bundle.rule and the attribute rule_name to set a specific alias for the rule:

For example:

<?php
use Somnambulist\Components\Validation\Rule;
use Ramsey\Uuid\Uuid;

class UuidRule extends Rule
{
    protected string $message = 'The :attribute is not a valid UUID or is NIL';

    public function check($value): bool
    {
        return Uuid::isValid($value) && $value !== Uuid::NIL;
    }
}
services:
    App\Rules\UuidRule:
        tags:
            - { name: 'somnambulist.form_request_bundle.rule', rule_name: 'uuid' }

Without the tag, this rule would be registered as: uuid_rule.

As rules are registered as services you can use other services for database or API checks etc.

See the documentation for more details on how to pass arguments, the available rules, and how to handle translation of messages.

Note: all rules must have unique names and same names will overwrite any pre-existing rules.

Note: several rules are needed internally; if you experience odd behaviour it could be because you changed the behaviour of a built-in rule.

Adding missing mime-types

somnambulist/validation includes a mime-type guesser that is registered by default and is available as a service. You can add additional mime-types and extensions to this by injecting the service and configuring it, either in a boot method or in a service.

Alternatively: the implementation can be replaced entirely provided it implements the MimeTypeGuesser interface.

Tests

PHPUnit 9+ is used for testing. Run tests via vendor/bin/phpunit.

You might also like...
Silverstripe-tinytidy - Control which styles are available in TinyMCE's style dropdown menu and what elements they can be applied to
Silverstripe-tinytidy - Control which styles are available in TinyMCE's style dropdown menu and what elements they can be applied to

TinyTidy for SilverStripe This module mainly serves as an example of how to customise the 'styles' dropdown menu in the TinyMCE editor to control whic

🙈 Code style configuration for `php-cs-fixer` based on PSR-12.

php-code-style Code style configuration for friendsofphp/php-cs-fixer based on PSR-12. Installation Step 1 of 3 Install gomzyakov/php-code-style via c

Provides an object-oriented API to query in-memory collections in a SQL-style.

POQ - PHP Object Query Install composer require alexandre-daubois/poq 1.0.0-beta2 That's it, ready to go! 🎉 Usage Here is the set of data we're going

Create an ip info WebPage with a style.css and an index.php

my-ip-info Create an ip info Page with a style.css and an index.php file. 支持 判断浏览器语言,非中文显示为英文。 curl指令返回ip地址 国家 城市。 在地图上显示位置 前提条件 一个已经注册了域名并在Cloudflare

Developer-friendly framework heavily inspired by Laravel and based on Timber and Wpemerge solutions for WordPress themes development with Bedrock folder structure

Lightweight Brocooly (Brocket) Improved Controllers, Middleware and Routers, but slightly less powerful Container Open beta. Package in development Cr

this starter kite inspired by laravel & Geo and mvc pattern. it's wrap for Wordpress built in classes.

WordpressStarterKite Introduction Built With Prerequisite Directory Structure Guidelines Getting Started Authors Introduction this starter kite inspir

A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package.

Net A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package. Features: No hard dependencies; Favours

A data transfer object inspired by Rust's serde

Data Transfer Object Want to deserialize an object with data on the fly? Go for it by using the From trait. How is this package any different from spa

A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package.

Net A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package. Features: No hard dependencies; Favours

Owner
Somnambulist Tech
Providing open source packages to help with web application development
Somnambulist Tech
Bundle providing Honeypot field for the Form Builder in Ibexa DXP Experience/Commerce (3.X)

IbexaHoneypot Bundle providing Honeypot field for the Form Builder in Ibexa DXP Experience/Commerce (3.X) What is Honey pot? A honey pot trap involves

null 1 Oct 14, 2021
A Symfony Feature Flag Bundle which easily allows you to configure and use your favorite feature flag provider.

Metro Markets FF Metro Markets FF is a Feature Flag Symfony Bundle. It easily allows you to configure and use your favorite feature flag provider. Ins

METRO Markets 14 May 23, 2022
A Symfony bundle built to schedule/consume repetitive tasks

Daily runs Code style Infection PHPUnit Rector Security Static analysis A Symfony bundle built to schedule/consume repetitive tasks Main features Exte

Guillaume Loulier 98 Jan 4, 2023
Tabler.io bundle for Symfony - a backend/admin theme for easy integration

Tabler Bundle for Symfony This repository contains a Symfony bundle, integrating the fantastic Tabler.io HTML Template into your Symfony project. It s

Kevin Papst 22 Jan 2, 2023
Symfony bundle for class/method memoization

Symfony service memoization bundle This bundle provides memoization for your services - every time you call the same method with the same arguments a

Dominik Chrástecký 16 Oct 31, 2022
Symfony Bundle to create HTML tables with bootstrap-table for Doctrine Entities.

HelloBootstrapTableBundle This Bundle provides simple bootstrap-table configuration for your Doctrine Entities. Used bootstrap-table version 1.18.3. I

Sebastian B 7 Nov 3, 2022
RSQueue Bundle for Symfony

RSQueueBundle for Symfony Simple queuing system based on Redis Table of contents Installing/Configuring Tags Installing Redis Installing PHPRedis Inst

RSQueue 11 Oct 8, 2018
🕧 Provides an scheduler bundle for symfony framework.

?? PHP Scheduler Bundle Provides the integration of the PHP Scheduler library into Symfony Framework. Installation Run composer require flexic/schedul

FlexicSystems 3 Nov 15, 2022
Laravel Pint is an opinionated PHP code style fixer for minimalists.

Laravel Pint is an opinionated PHP code style fixer for minimalists. Pint is built on top of PHP-CS-Fixer and makes it simple to ensure that your code style stays clean and consistent.

The Laravel Framework 2.2k Jan 5, 2023
A simple twitter-feed-style RSS aggregator written in PHP, Laravel, Inertia.js, Tailwind and Vue.js

RSS A simple, opinionated, RSS feed aggregator. Features The following features are built into the application: Supports RSS and ATOM formats. Regular

Dan Brown 257 Dec 24, 2022