Avav Smith

Avav Smith

1578555036

Simple Vuex Module to Handle Form Fields and Validations.

Simple Vuex module to handle form fields and validations.

vuex-module-validatable-state

You can build a view model for your form, which runs valdations easily. You just provide initial fields and validators to build the module, then map getters/actions to components.

Usage

Installation

$ npm i vuex-module-validatable-state

Register to core Vuex module

This module provides the function to return Vuex module as default. The function takes arguments:

  • Initial field set
  • Validators

A. Define directly

import validatableModule from "vuex-module-validatable-state";

const initialFields = {
  amount: null,
  description: "default text"
};

const validators = {
  amount: [
    ({ amount }) => amount === null ? "Require this" : false
  ],
  description: [
    ({ description }) => description.length > 15 ? "Should be shorter than 15" : false,
    ({ description, amount }) => description.indexOf(amount.toString())  ? "Should include amount" : false,
  ]
};

new Vuex.Store({
  modules: {
    myForm: {
      namespaced: true
      store,
      getters,
      actions,
      mutations,
      modules: {
        ...validatableModule(initialFields, validators) // <-- HERE
      }
    }
  }
});

B. Register to existing module

import { register } from "vuex-module-validatable-state";

const initialFields = {
  amount: null,
  description: "default text"
};

const validators = {
  amount: [
    ({ amount }) => amount === null ? "Require this" : false
  ],
  description: [
    ({ description }) => description.length > 15 ? "Should be shorter than 15" : false,
    ({ description, amount }) => description.indexOf(amount.toString())  ? "Should include amount" : false,
  ]
};

const store = new Vuex.Store({
  modules: {
    myForm: {
      namespaced: true
      store,
      getters,
      actions,
      mutations
    }
  }
});

register(store, "myForm", initialFields, validators);

Map to Components

Provided Getters

Getter name Returns
GetterTypes.ALL_FIELDS_VALID boolean whether all fields don’t have error
GetterTypes.FIELD_VALUES All fields as { [fieldName]: value }
GetterTypes.FIELD_ERRORS All errors as { [fieldName]: errorMessage }
GetterTypes.FIELD_EDITABILITIES All editable flags as { [fieldName]: editability }
GetterTypes.FIELD_DIRTINESSES All dirtiness flags as { [fieldName]: dirtiness }
GetterTypes.ANY_FIELD_CHANGED boolean whether all fields are not dirty

Provided Actions

Import ActionTypes from the module.

Action name Runs
ActionTypes.SET_FIELD Set value for a field, then runs validation if enabled
ActionTypes.SET_FIELDS_BULK Set values for fields at once, then make all dirtiness flags false
ActionTypes.RESET_FIELDS Reset values on field with initial values
ActionTypes.ENABLE_ALL_VALIDATIONS Enable interactive validation and run validations for all fields
ActionTypes.VALIDATE_FIELD_VALUE Validate specific field
ActionTypes.VALIDATE_FIELDS Validate all fields
ActionTypes.SET_FIELDS_EDITABILITY Set editability flag for a field, disabled field is not updated nor validated
ActionTypes.SET_FIELDS_PRISTINE Make all dirtiness flags false

Validators

You can pass validators when you initialize the module.

const validators = {
  amount: [/* validators for filling error against to amount */],
  description: [/* validators for filling error against to description */]
}

Each validator can take all fields values to run validation:

const validators = {
  amount: [
    ({ amount, description }) => /* return false or errorMessage */
  ]
}

Optionally, can take getters on the store which calls this module:

const validators = {
  description: [
    ({ description }, getters) => getters.getterOnStore && validationLogicIfGetterOnStoreIsTruthy(description)
  ]
}

And you can request “interactive validation” which valites every time dispatch(ActionTypes.SET_FIELD) is called

const validators = {
  amount: [
    [({ amount }, getters) => /* validator logic */, { instant: true }]
  ]
}

Provided Typings

You can import handy type/interface definitions from the module. The generic T in below expects fields type like:

interface FieldValues {
  amount: number;
  description: string;
}

getters[GetterTypes.FIELD_VALUES] returns values with following FieldValues interface.

See all typings

ValidatorTree<T>

As like ActionTree, MutationTree, you can receive type guards for Validators. By giving your fields’ type for Generics, validator can get more guards for each fields:

ValidatorTree

SetFieldAction<T>

It’s the type definition of the payload for dispatching ActionTypes.SET_FIELD, you can get type guard for your fields by giving Generics.

SetFieldAction

FieldValidationErrors<T>

Type for getters[GetterTypes.FIELD_ERRORS]

FieldEditabilities<T>

Type for getters[GetterTypes.FIELD_EDITABILITIES]

FieldDirtinesses<T>

Type for getters[GetterTypes.FIELD_DIRTINESSES]

Working Sample

Edit Sample: vuex-module-validatable-state

Registering to Vuex Store

const initialField = {
  amount: 0,
  description: null
};

const validators = {
  amount: [
    ({ amount }) => (!amount ? "Amount is required" : false),
    ({ amount }) => (amount <= 0 ? "Amount should be greater than 0" : false)
  ],
  description: [
    ({ amount, description }) =>
      amount > 1000 && !description
        ? "Description is required if amount is high"
        : false
  ]
};

const store = new Vuex.Store({
  modules: {
    ...theModule(initialField, validators)
  }
});

Mapping to Component

<template>
  <form>
    <div>
      <label for="amount">Amount (Required, Positive)</label>
      <input type="number" name="amount" v-model="amount">
      <span v-if="errors.amount">{{ errors.amount }}</span>
    </div>
    <div>
      <label for="description">Description (Required if amount is greater than 1000)</label>
      <textarea name="description" v-model="description"/>
      <span v-if="errors.description">{{ errors.description }}</span>
    </div>
    <button @click.prevent="submit">Validate and Submit</button>
  </form>
</template>

<script>
import { GetterTypes, ActionTypes } from "vuex-module-validatable-state";

export default {
  name: "App",
  computed: {
    amount: {
      get() {
        return this.$store.getters[GetterTypes.FIELD_VALUES].amount;
      },
      set(value) {
        this.$store.dispatch(ActionTypes.SET_FIELD_VALUE, {
          name: "amount",
          value
        });
      }
    },
    description: {
      get() {
        return this.$store.getters[GetterTypes.FIELD_VALUES].description;
      },
      set(value) {
        this.$store.dispatch(ActionTypes.SET_FIELD_VALUE, {
          name: "description",
          value
        });
      }
    },
    errors() {
      return this.$store.getters[GetterTypes.FIELD_ERRORS];
    }
  },
  methods: {
    submit() {
      this.$store.dispatch(ActionTypes.ENABLE_ALL_VALIDATIONS).then(() => {
        if (this.$store.getters[GetterTypes.ALL_FIELDS_VALID]) {
          alert("Form is valid, so now submitting!");
          this.$store.dispatch(ActionTypes.SET_FIELDS_PRISTINE);
        }
      });
    }
  }
};
</script>

Demo || Download


Thank for read!

#vuex #vuex-module #vue-form #vue-form-validate

What is GEEK

Buddha Community

Simple Vuex Module to Handle Form Fields and Validations.
Avav Smith

Avav Smith

1578555036

Simple Vuex Module to Handle Form Fields and Validations.

Simple Vuex module to handle form fields and validations.

vuex-module-validatable-state

You can build a view model for your form, which runs valdations easily. You just provide initial fields and validators to build the module, then map getters/actions to components.

Usage

Installation

$ npm i vuex-module-validatable-state

Register to core Vuex module

This module provides the function to return Vuex module as default. The function takes arguments:

  • Initial field set
  • Validators

A. Define directly

import validatableModule from "vuex-module-validatable-state";

const initialFields = {
  amount: null,
  description: "default text"
};

const validators = {
  amount: [
    ({ amount }) => amount === null ? "Require this" : false
  ],
  description: [
    ({ description }) => description.length > 15 ? "Should be shorter than 15" : false,
    ({ description, amount }) => description.indexOf(amount.toString())  ? "Should include amount" : false,
  ]
};

new Vuex.Store({
  modules: {
    myForm: {
      namespaced: true
      store,
      getters,
      actions,
      mutations,
      modules: {
        ...validatableModule(initialFields, validators) // <-- HERE
      }
    }
  }
});

B. Register to existing module

import { register } from "vuex-module-validatable-state";

const initialFields = {
  amount: null,
  description: "default text"
};

const validators = {
  amount: [
    ({ amount }) => amount === null ? "Require this" : false
  ],
  description: [
    ({ description }) => description.length > 15 ? "Should be shorter than 15" : false,
    ({ description, amount }) => description.indexOf(amount.toString())  ? "Should include amount" : false,
  ]
};

const store = new Vuex.Store({
  modules: {
    myForm: {
      namespaced: true
      store,
      getters,
      actions,
      mutations
    }
  }
});

register(store, "myForm", initialFields, validators);

Map to Components

Provided Getters

Getter name Returns
GetterTypes.ALL_FIELDS_VALID boolean whether all fields don’t have error
GetterTypes.FIELD_VALUES All fields as { [fieldName]: value }
GetterTypes.FIELD_ERRORS All errors as { [fieldName]: errorMessage }
GetterTypes.FIELD_EDITABILITIES All editable flags as { [fieldName]: editability }
GetterTypes.FIELD_DIRTINESSES All dirtiness flags as { [fieldName]: dirtiness }
GetterTypes.ANY_FIELD_CHANGED boolean whether all fields are not dirty

Provided Actions

Import ActionTypes from the module.

Action name Runs
ActionTypes.SET_FIELD Set value for a field, then runs validation if enabled
ActionTypes.SET_FIELDS_BULK Set values for fields at once, then make all dirtiness flags false
ActionTypes.RESET_FIELDS Reset values on field with initial values
ActionTypes.ENABLE_ALL_VALIDATIONS Enable interactive validation and run validations for all fields
ActionTypes.VALIDATE_FIELD_VALUE Validate specific field
ActionTypes.VALIDATE_FIELDS Validate all fields
ActionTypes.SET_FIELDS_EDITABILITY Set editability flag for a field, disabled field is not updated nor validated
ActionTypes.SET_FIELDS_PRISTINE Make all dirtiness flags false

Validators

You can pass validators when you initialize the module.

const validators = {
  amount: [/* validators for filling error against to amount */],
  description: [/* validators for filling error against to description */]
}

Each validator can take all fields values to run validation:

const validators = {
  amount: [
    ({ amount, description }) => /* return false or errorMessage */
  ]
}

Optionally, can take getters on the store which calls this module:

const validators = {
  description: [
    ({ description }, getters) => getters.getterOnStore && validationLogicIfGetterOnStoreIsTruthy(description)
  ]
}

And you can request “interactive validation” which valites every time dispatch(ActionTypes.SET_FIELD) is called

const validators = {
  amount: [
    [({ amount }, getters) => /* validator logic */, { instant: true }]
  ]
}

Provided Typings

You can import handy type/interface definitions from the module. The generic T in below expects fields type like:

interface FieldValues {
  amount: number;
  description: string;
}

getters[GetterTypes.FIELD_VALUES] returns values with following FieldValues interface.

See all typings

ValidatorTree<T>

As like ActionTree, MutationTree, you can receive type guards for Validators. By giving your fields’ type for Generics, validator can get more guards for each fields:

ValidatorTree

SetFieldAction<T>

It’s the type definition of the payload for dispatching ActionTypes.SET_FIELD, you can get type guard for your fields by giving Generics.

SetFieldAction

FieldValidationErrors<T>

Type for getters[GetterTypes.FIELD_ERRORS]

FieldEditabilities<T>

Type for getters[GetterTypes.FIELD_EDITABILITIES]

FieldDirtinesses<T>

Type for getters[GetterTypes.FIELD_DIRTINESSES]

Working Sample

Edit Sample: vuex-module-validatable-state

Registering to Vuex Store

const initialField = {
  amount: 0,
  description: null
};

const validators = {
  amount: [
    ({ amount }) => (!amount ? "Amount is required" : false),
    ({ amount }) => (amount <= 0 ? "Amount should be greater than 0" : false)
  ],
  description: [
    ({ amount, description }) =>
      amount > 1000 && !description
        ? "Description is required if amount is high"
        : false
  ]
};

const store = new Vuex.Store({
  modules: {
    ...theModule(initialField, validators)
  }
});

Mapping to Component

<template>
  <form>
    <div>
      <label for="amount">Amount (Required, Positive)</label>
      <input type="number" name="amount" v-model="amount">
      <span v-if="errors.amount">{{ errors.amount }}</span>
    </div>
    <div>
      <label for="description">Description (Required if amount is greater than 1000)</label>
      <textarea name="description" v-model="description"/>
      <span v-if="errors.description">{{ errors.description }}</span>
    </div>
    <button @click.prevent="submit">Validate and Submit</button>
  </form>
</template>

<script>
import { GetterTypes, ActionTypes } from "vuex-module-validatable-state";

export default {
  name: "App",
  computed: {
    amount: {
      get() {
        return this.$store.getters[GetterTypes.FIELD_VALUES].amount;
      },
      set(value) {
        this.$store.dispatch(ActionTypes.SET_FIELD_VALUE, {
          name: "amount",
          value
        });
      }
    },
    description: {
      get() {
        return this.$store.getters[GetterTypes.FIELD_VALUES].description;
      },
      set(value) {
        this.$store.dispatch(ActionTypes.SET_FIELD_VALUE, {
          name: "description",
          value
        });
      }
    },
    errors() {
      return this.$store.getters[GetterTypes.FIELD_ERRORS];
    }
  },
  methods: {
    submit() {
      this.$store.dispatch(ActionTypes.ENABLE_ALL_VALIDATIONS).then(() => {
        if (this.$store.getters[GetterTypes.ALL_FIELDS_VALID]) {
          alert("Form is valid, so now submitting!");
          this.$store.dispatch(ActionTypes.SET_FIELDS_PRISTINE);
        }
      });
    }
  }
};
</script>

Demo || Download


Thank for read!

#vuex #vuex-module #vue-form #vue-form-validate

Yogi Gurjar

1600308055

Laravel 8 Form Validation Tutorial

Laravel 8 form validation example. In this tutorial, i will show you how to submit form with validation in laravel 8.

And you will learn how to store form data in laravel 8. Also validate form data before store to db.

How to Validate Form Data in Laravel 8

  1. Step 1 – Install Laravel 8 Application
  2. Step 2 – Configuring Database using Env File
  3. Step 3 – Create Model & Migration File For Form
  4. Step 4 – Create Routes
  5. Step 5 – Creating Controller
  6. Step 6 – Create Blade File For Form
  7. Step 7 – Start Development Server
  8. Step 8 – Run Laravel 8 Form Validation App On Browser

https://laratutorials.com/laravel-8-form-validation-example-tutorial/

#laravel 8 form validation #laravel 8 form validation tutorial #laravel 8 form validation - google search #how to validate form data in laravel 8 #form validation in laravel 8

Laravel 8 Form Validation Example

In this tutorial we will see laravel 8 form validation example, form validation in laravel is very common functionalities and it is use in each and every website to validate form field.

Here, We will use has function in session to check error message in laravel 8. using this example you can check simple form validation as well as you can create your own custom validation in laravel 8.

Laravel 8 Form Validation Example

https://websolutionstuff.com/post/laravel-8-form-validation-example


Read Also : Laravel 8 CRUD Operation Example

https://websolutionstuff.com/post/laravel-8-crud-operation-example

#laravel 8 form validation example #form validation #how to validate form in laravel 8 #form validation in laravel #laravel #laravel8

Controller Extra Bundle for Symfony2

ControllerExtra for Symfony2

This bundle provides a collection of annotations for Symfony2 Controllers, designed to streamline the creation of certain objects and enable smaller and more concise actions.

Reference

By default, all annotations are loaded, but any individual annotation can be completely disabled by setting to false active parameter.

Default values are:

controller_extra:
    resolver_priority: -8
    request: current
    paginator:
        active: true
        default_name: paginator
        default_page: 1
        default_limit_per_page: 10
    entity:
        active: true
        default_name: entity
        default_persist: true
        default_mapping_fallback: false
        default_factory_method: create
        default_factory_mapping: true
    form:
        active: true
        default_name: form
    object_manager:
        active: true
        default_name: form
    flush:
        active: true
        default_manager: default
    json_response:
        active: true
        default_status: 200
        default_headers: []
    log:
        active: true
        default_level: info
        default_execute: pre

ResolverEventListener is subscribed to kernel.controller event with priority -8. This element can be configured and customized with resolver_priority config value. If you need to get ParamConverter entities, make sure that this value is lower than 0. The reason is that this listener must be executed always after ParamConverter one.

Entity provider

In some annotations, you can define an entity by several ways. This chapter is about how you can define them.

By namespace

You can define an entity using its namespace. A simple new new() be performed.

/**
 * Simple controller method
 *
 * @SomeAnnotation(
 *      class = "Mmoreram\CustomBundle\Entity\MyEntity",
 * )
 */
public function indexAction()
{
}

By doctrine shortcut

You can define an entity using Doctrine shortcut notations. With this format you should ensure that your Entities follow Symfony Bundle standards and your entities are placed under Entity/ folder.

/**
 * Simple controller method
 *
 * @SomeAnnotation(
 *      class = "MmoreramCustomBundle:MyEntity",
 * )
 */
public function indexAction()
{
}

By parameter

You can define an entity using a simple config parameter. Some projects use parameters to define all entity namespaces (To allow overriding). If you define the entity with a parameter, this bundle will try to instance it with a simple new() accessing directly to the container ParametersBag.

parameters:

    #
    # Entities
    #
    my.bundle.entity.myentity: Mmoreram\CustomBundle\Entity\MyEntity
/**
 * Simple controller method
 *
 * @SomeAnnotation(
 *      class = "my.bundle.entity.myentity",
 * )
 */
public function indexAction()
{
}

Controller annotations

This bundle provide a reduced but useful set of annotations for your controller actions.

@CreatePaginator

Creates a Doctrine Paginator object, given a request and a configuration. This annotation just injects into de controller a new Doctrine\ORM\Tools\Pagination\Pagination instance ready to be iterated.

You can enable/disable this bundle by overriding active flag in configuration file config.yml

controller_extra:
    pagination:
        active: true

By default, if name option is not set, the generated object will be placed in a parameter named $paginator. This behaviour can be configured using default_name in configuration.

This annotation can be configured with these sections

Paginator Entity

To create a new Pagination object you need to refer to an existing Entity. You can check all available formats you can define it just reading the Entity Provider section.

<?php

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator page

You need to specify Paginator annotation the page to fetch. By default, if none is specified, this bundle will use the default one defined in configuration. You can override in config.yml

controller_extra:
    pagination:
        default_page: 1

You can refer to an existing Request attribute using ~value~ format, to any $_GET element by using format ?field? or to any $_POST by using format #field#

You can choose between Master Request or Current Request accessing to its attributes, by configuring the request value of the configuration.

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/{foo}
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = "~foo~"
 * )
 */
public function indexAction(Paginator $paginator)
{
}

or you can hardcode the page to use.

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = 1
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator limit

You need to specify Paginator annotation the limit to fetch. By default, if none is specified, this bundle will use the default one defined in configuration. You can override in config.yml

controller_extra:
    pagination:
        default_limit_per_page: 10

You can refer to an existing Request attribute using ~value~ format, to any $_GET element by using format ?field? or to any $_POST by using format #field#

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/{foo}/{limit}
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = "~foo~",
 *      limit = "~limit~"
 * )
 */
public function indexAction(Paginator $paginator)
{
}

or you can hardcode the page to use.

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = 1,
 *      limit = 10
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator OrderBy

You can order your Pagination just defining the fields you want to orderBy and the desired direction. The orderBy section must be defined as an array of arrays, and each array should contain these positions:

  • First position: Entity alias (Principal object is set as x)
  • Second position: Entity field
  • Third position: Direction
  • Fourth position: Custom direction map (optional)
use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      orderBy = {
 *          {"x", "createdAt", "ASC"},
 *          {"x", "updatedAt", "DESC"},
 *          {"x", "id", 1, {
 *              0 => "ASC",
 *              1 => "DESC",
 *          }},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

With the third and fourth value you can define a map where to match your own direction nomenclature with DQL one. DQL nomenclature just accept ASC for Ascendant and DESC for Descendant.

This is very useful when you need to match a url format with the DQL one. You can refer to an existing Request attribute using ~value~ format, to any $_GET element by using format ?field? or to any $_POST by using format #field#

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/order/{field}/{direction}
 *
 * For example, some matchings...
 *
 * /myroute/paginate/order/id/1 -> ORDER BY id DESC
 * /myroute/paginate/order/enabled/0 - ORDER BY enabled ASC
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      orderBy = {
 *          {"x", "createdAt", "ASC"},
 *          {"x", "updatedAt", "DESC"},
 *          {"x", "~field~", ~direction~, {
 *              0 => "ASC",
 *              1 => "DESC",
 *          }},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

The order of the definitions will alter the order of the DQL query.

Paginator Wheres

You can define some where statements in your Paginator. The wheres section must be defined as an array of arrays, and each array should contain these positions:

  • First position: Entity alias (Principal object is set as x)
  • Second position: Entity field
  • Third position: Operator =, <=, >, LIKE...
  • Fourth position: Value to compare with
  • Fifth position: Is a filter. By default, false
use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      wheres = {
 *          {"x", "enabled", "=", true},
 *          {"x", "age", ">", 18},
 *          {"x", "name", "LIKE", "Eferv%"},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

You can refer to an existing Request attribute using ~value~ format, to any $_GET element by using format ?field? or to any $_POST by using format #field#

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/{field}
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      wheres = {
 *          {"x", "name", "LIKE", "~field~"},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

You can use as well this feature for optional filtering by setting the last position to true. In that case, if the filter value is not found, such line will be ignored.

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute?query=name%
 * This Controller matches pattern /myroute as well
 *
 * In both cases this will work. In the first case we will apply the where line
 * in the paginator. In the second case, we wont.
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      wheres = {
 *          {"x", "name", "LIKE", "?query?", true},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator Not Nulls

You can also define some fields to not null. Is same as wheres section, but specific for NULL assignments. The notNulls section must be defined as an array of arrays, and each array should contain these positions:

  • First position: Object (Principal object is set as x)
  • Second position: Field
use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      notNulls = {
 *          {"x", "enabled"},
 *          {"x", "deleted"},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator Left Join

You can do some left joins in this section. The leftJoins section must be defined as an array of array, where each array can have these fields:

  • First position: Entity alias (Principal object is set as x)
  • Second position: Entity relation (Address)
  • Third position: Relation identifier (a)
  • Fourth position: If true, this relation is added in select group. Otherwise, wont be loaded until its request (optional)
use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      leftJoins = {
 *          {"x", "User", "u", true},
 *          {"x", "Address", "a", true},
 *          {"x", "Cart", "c"},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator Inner Join

You can do some inner joins in this section. The innerJoins section must be defined as an array of array, where each array can have these fields:

  • First position: Entity alias (x)
  • Second position: Entity relation (Address)
  • Third position: Relation identifier (a)
  • Fourth position: If true, this relation is added in select group. Otherwise, wont be loaded until its request (optional)
use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      innerJoins = {
 *          {"x", "User", "u", true},
 *          {"x", "Address", "a", true},
 *          {"x", "Cart", "c"},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

Paginator Attributes

A nice feature of this annotation is that you can also inject into your controller a Mmoreram\ControllerExtraBundle\ValueObject\PaginatorAttributes instance with some interesting information about your pagination.

  • currentPage : Current page fetched
  • totalElements : Total elements given your criteria. If none criteria is defined in your configuration, this value will show all elements of a certain entity.
  • totalPages : Total pages you can fetch given a criteria.
  • limitPerPage: Maximum number of elements in each page.

To inject this object you need to define the "attributes" annotation field with the method parameter name.

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;
use Mmoreram\ControllerExtraBundle\ValueObject\PaginatorAttributes;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/
 *
 * @CreatePaginator(
 *      attributes = "paginatorAttributes",
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = 1,
 *      limit = 10
 * )
 */
public function indexAction(
    Paginator $paginator,
    PaginatorAttributes $paginatorAttributes
)
{
    $currentPage = $paginatorAttributes->getCurrentPage();
    $totalElements = $paginatorAttributes->getTotalElements();
    $totalPages = $paginatorAttributes->getTotalPages();
    $limitPerPage = $paginatorAttributes->getLimitPerPage();

}

Paginator Example

This is a completed example and its DQL resolution

use Doctrine\ORM\Tools\Pagination\Pagination;
use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;

/**
 * Simple controller method
 *
 * This Controller matches pattern /paginate/nb/{limit}/{page}
 *
 * Where:
 *
 * * limit = 10
 * * page = 1
 *
 * @CreatePaginator(
 *      entityNamespace = "ControllerExtraBundle:Fake",
 *      page = "~page~",
 *      limit = "~limit~",
 *      orderBy = {
 *          { "x", "createdAt", "ASC" },
 *          { "x", "updatedAt", "DESC" },
 *          { "x", "id", "0", {
 *              "1" = "ASC",
 *              "2" = "DESC",
 *          }}
 *      },
 *      wheres = {
 *          { "x", "enabled" , "=", true }
 *      },
 *      leftJoins = {
 *          { "x", "relation", "r" },
 *          { "x", "relation2", "r2" },
 *          { "x", "relation5", "r5", true },
 *      },
 *      innerJoins = {
 *          { "x", "relation3", "r3" },
 *          { "x", "relation4", "r4", true },
 *      },
 *      notNulls = {
 *          {"x", "address1"},
 *          {"x", "address2"},
 *      }
 * )
 */
public function indexAction(Paginator $paginator)
{
}

The DQL generated by this annotation is

    SELECT x, r4, r5
    FROM Mmoreram\\ControllerExtraBundle\\Tests\\FakeBundle\\Entity\\Fake x

    INNER JOIN x.relation3 r3
    INNER JOIN x.relation4 r4

    LEFT JOIN x.relation r
    LEFT JOIN x.relation2 r2
    LEFT JOIN x.relation5 r5

    WHERE enabled = ?where0
    AND x.address1 IS NOT NULL
    AND x.address2 IS NOT NULL

    ORDER BY createdAt ASC, id ASC

PagerFanta Add-on

This annotation can create a PagerFanta instance if you need it. You only have to define your parameter as such, and the annotation resolver will wrap your paginator with a Pagerfanta object instance.

use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;
use Pagerfanta\Pagerfanta;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = 1,
 *      limit = 10
 * )
 */
public function indexAction(Pagerfanta $paginator)
{
}

KNPPaginator Add-on

This annotation can create a KNPPaginator instance if you need it. You only have to define your parameter as such, and the annotation resolver will wrap your paginator with a KNPPaginator object instance.

use Mmoreram\ControllerExtraBundle\Annotation\CreatePaginator;
use Knp\Component\Pager\Pagination\PaginationInterface;

/**
 * Simple controller method
 *
 * This Controller matches pattern /myroute/paginate/
 *
 * @CreatePaginator(
 *      entityNamespace = "MmoreramCustomBundle:User",
 *      page = 1,
 *      limit = 10
 * )
 */
public function indexAction(PaginationInterface $paginator)
{
}

@LoadEntity

Loads an entity from your database, or creates a new one.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Entity;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @Entity(
 *      namespace = "MmoreramCustomBundle:User",
 *      name  = "user"
 * )
 */
public function indexAction(User $user)
{
}

By default, if name option is not set, the generated object will be placed in a parameter named $entity. This behaviour can be configured using default_name in configuration.

You can also use setters in Entity annotation. It means that you can simply call entity setters using Request attributes.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Entity;
use Mmoreram\ControllerExtraBundle\Entity\Address;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @Entity(
 *      namespace = "MmoreramCustomBundle:Address",
 *      name  = "address"
 * )
 * @Entity(
 *      namespace = "MmoreramCustomBundle:User",
 *      name  = "user",
 *      setters = {
 *          "setAddress": "address"
 *      }
 * )
 */
public function indexAction(Address $address, User $user)
{
}

When User instance is built, method setAddress is called using as parameter the new Address instance.

New entities are just created with a simple new(), so they are not persisted. By default, they will be persisted using configured manager, but you can disable this feature using persist option.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Entity;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @Entity(
 *      namespace = "MmoreramCustomBundle:User",
 *      name  = "user",
 *      persist = false
 * )
 */
public function indexAction(User $user)
{
}

Entity Mapping

When you define a new Entity annotation, you can also request the mapped entity given a map. It means that if a map is defined, this bundle will try to request the mapped instance satisfying it.

The keys of the map represent the names of the mapped fields and the values represent their desired values. Remember than you can refer to any Request attribute by using format ~field~, to any $_GET element by using format ?field? or to any $_POST by using format #field#

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Entity;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * This Controller matches pattern /user/edit/{id}/{username}
 *
 * @Entity(
 *      namespace = "MmoreramCustomBundle:User",
 *      name  = "user",
 *      mapping = {
 *          "id": "~id~",
 *          "username": "~username~"
 *      }
 * )
 */
public function indexAction(User $user)
{
}

In this case, you will try to get the mapped instance of User with passed id. If some mapping is defined and any entity is found, a new EntityNotFoundException` is thrown.

Entity Mapping Fallback

So what if one ore more than one mapping references are not found? For example, you're trying to map the {id} parameter from your route, but this parameter is not even defined. Whan happens here? Well, you can assume then that you want to pass a new entity instance by using the mappingFallback.

By default, if mapping_fallback option is not set, the used value will be the parameter default_mapping_fallback defined in configuration. By default this value is false

Don't confuse with the scenario where you're looking for an entity in your database, all mapping references have been resolved, and the entity is not found. In that case, a common "EntityNotFound" exception will be thrown by Doctrine.

Lets see an example. Because we have enabled the mappingFallback, and because the mapping definition does not match the assigned route, we will return a new empty User entity.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Entity;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * This Controller matches pattern /user/edit/{id}
 *
 * @LoadEntity(
 *      namespace = "MmoreramCustomBundle:User",
 *      name  = "user",
 *      mapping = {
 *          "id": "~id~",
 *          "username": "~nonexisting~"
 *      },
 *      mappingFallback = true
 * )
 */
public function indexAction(User $user)
{
    // $user->getId() === null
}

Entity Repository

By default, the Doctrine entity manager provides the right repository per each entity (not the default one, but the right specific one). Although, you can define a custom repository to be used in your annotation by using the repository configuration.

/**
 * Simple controller method
 *
 * @CreateEntity(
 *      namespace = "MmoreramCustomBundle:User",
 *      mapping = {
 *          "id": "~id~",
 *          "username": "~username~"
 *      }
 *      repository = {
 *          "class" = "Mmoreram\CustomBundle\Repository\AnotherRepository",
 *      },
 * )
 */
public function indexAction(User $user)
{
}

By default, the method findOneBy will always be used, unless you define another one.

/**
 * Simple controller method
 *
 * @CreateEntity(
 *      namespace = "MmoreramCustomBundle:User",
 *      mapping = {
 *          "id": "~id~",
 *          "username": "~username~"
 *      }
 *      repository = {
 *          "class" = "Mmoreram\CustomBundle\Repository\AnotherRepository",
 *          "method" = "find",
 *      },
 * )
 */
public function indexAction(User $user)
{
}

Entity Factory

When the annotation considers that a new entity must be created, because no mapping information has been provided, or because the mapping fallback has been activated, by default a new instance will be created by using the namespace value.

This configuration block has three positions

  • class - factory class
  • method - Method to use when retrieving the object
  • static - Method is static

You can define the factory with a simple namespace

/**
 * Simple controller method
 *
 * @CreateEntity(
 *      namespace = "MmoreramCustomBundle:User",
 *      factory = {
 *          "class" = "Mmoreram\CustomBundle\Factory\UserFactory",
 *          "method" = "create",
 *          "static" = true,
 *      },
 * )
 */
public function indexAction(User $user)
{
}

If you want to define your Factory as a service, with the possibility of overriding namespace, you can simply define service name. All other options have the same behaviour.

parameters:

    #
    # Factories
    #
    my.bundle.factory.user_factory: Mmoreram\CustomBundle\Factory\UserFactory
/**
 * Simple controller method
 *
 * @CreateEntity(
 *      class = {
 *          "factory" = my.bundle.factory.user_factory,
 *          "method" = "create",
 *          "static" = true,
 *      },
 * )
 */
public function indexAction(User $user)
{
}

If you do not define the method, default one will be used. You can override this default value by defining new one in your config.yml. Same with static value

controller_extra:
    entity:
        default_factory_method: create
        default_factory_static: true

@CreateForm

Provides form injection in your controller actions. This annotation only needs a name to be defined in, where you must define namespace where your form is placed.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;
use Symfony\Component\Form\AbstractType;

/**
 * Simple controller method
 *
 * @CreateForm(
 *      class = "\Mmoreram\CustomBundle\Form\Type\UserType",
 *      name  = "userType"
 * )
 */
public function indexAction(AbstractType $userType)
{
}

By default, if name option is not set, the generated object will be placed in a parameter named $form. This behaviour can be configured using default_name in configuration.

You can not just define your Type location using the namespace, in which case a new AbstractType element will be created. but you can also define it using service alias, in which case this bundle will return an instance using Symfony DI.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;
use Symfony\Component\Form\AbstractType;

/**
 * Simple controller method
 *
 * @CreateForm(
 *      class = "user_type",
 *      name  = "userType"
 * )
 */
public function indexAction(AbstractType $userType)
{
}

This annotation allows you to not only create an instance of FormType, but also allows you to inject a Form object or a FormView object

To inject a Form object you only need to cast method value as such.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;
use Symfony\Component\Form\Form;

/**
 * Simple controller method
 *
 * @CreateForm(
 *      class = "user_type",
 *      name  = "userForm"
 * )
 */
public function indexAction(Form $userForm)
{
}

You can also, using [SensioFrameworkExtraBundle][1]'s [ParamConverter][2], create a Form object with an previously created entity. you can define this entity using entity parameter.

<?php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Form\Form;

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @Route(
 *      path = "/user/{id}",
 *      name = "view_user"
 * )
 * @ParamConverter("user", class="MmoreramCustomBundle:User")
 * @CreateForm(
 *      class  = "user_type",
 *      entity = "user"
 *      name   = "userForm",
 * )
 */
public function indexAction(User $user, Form $userForm)
{
}

To handle current request, you can set handleRequest to true. By default this value is set to false

<?php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Form\Form;

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @Route(
 *      path = "/user/{id}",
 *      name = "view_user"
 * )
 * @ParamConverter("user", class="MmoreramCustomBundle:User")
 * @CreateForm(
 *      class         = "user_type",
 *      entity        = "user"
 *      handleRequest = true,
 *      name          = "userForm",
 * )
 */
public function indexAction(User $user, Form $userForm)
{
}

You can also add as a method parameter if the form is valid, using validate setting. Annotation will place result of $form->isValid() in specified method argument.

<?php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Form\Form;

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @Route(
 *      path = "/user/{id}",
 *      name = "view_user"
 * )
 * @ParamConverter("user", class="MmoreramCustomBundle:User")
 * @CreateForm(
 *      class         = "user_type",
 *      entity        = "user"
 *      handleRequest = true,
 *      name          = "userForm",
 *      validate      = "isValid",
 * )
 */
public function indexAction(User $user, Form $userForm, $isValid)
{
}

To inject a FormView object you only need to cast method variable as such.

<?php

use Symfony\Component\Form\FormView;

use Mmoreram\ControllerExtraBundle\Annotation\CreateForm;

/**
 * Simple controller method
 *
 * @CreateForm(
 *      class = "user_type",
 *      name  = "userFormView"
 * )
 */
public function indexAction(FormView $userFormView)
{
}

@Flush

Flush annotation allows you to flush entityManager at the end of request using kernel.response event

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Flush;

/**
 * Simple controller method
 *
 * @Flush
 */
public function indexAction()
{
}

If not otherwise specified, default Doctrine Manager will be flushed with this annotation. You can overwrite default Manager in your config.yml file.

controller_extra:
    flush:
        default_manager: my_custom_manager

You can also override this value in every single Flush Annotation instance defining manager value

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Flush;

/**
 * Simple controller method
 *
 * @Flush(
 *      manager = "my_own_manager"
 * )
 */
public function indexAction()
{
}

If you want to change default manager in all annotation instances, you should override bundle parameter in your config.yml file.

controller_extra:
    flush:
        default_manager: my_own_manager

If any parameter is set, annotation will flush all. If you only need to flush one or many entities, you can define explicitly which entity must be flushed.

<?php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

use Mmoreram\ControllerExtraBundle\Annotation\Flush;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @ParamConverter("user", class="MmoreramCustomBundle:User")
 * @Flush(
 *      entity = "user"
 * )
 */
public function indexAction(User $user)
{
}

You can also define a set of entities to flush

<?php

use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

use Mmoreram\ControllerExtraBundle\Annotation\Flush;
use Mmoreram\ControllerExtraBundle\Entity\Address;
use Mmoreram\ControllerExtraBundle\Entity\User;

/**
 * Simple controller method
 *
 * @ParamConverter("user", class="MmoreramCustomBundle:User")
 * @ParamConverter("address", class="MmoreramCustomBundle:Address")
 * @Flush(
 *      entity = {
 *          "user", 
 *          "address"
 *      }
 * )
 */
public function indexAction(User $user, Address $address)
{
}

If multiple @Mmoreram\Flush are defined in same action, last instance will overwrite previous. Anyway just one instance should be defined.

@ToJsonResponse

JsonResponse annotation allows you to create a Symfony\Component\HttpFoundation\JsonResponse object, given a simple controller return value.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\ToJsonResponse;

/**
 * Simple controller method
 *
 * @ToJsonResponse
 */
public function indexAction(User $user, Address $address)
{
    return array(
        'This is my response'
    );
}

By default, JsonResponse is created using default status and headers defined in bundle parameters. You can overwrite them in your config.yml file.

controller_extra:
    json_response:
        default_status: 403
        default_headers:
            "User-Agent": "Googlebot/2.1"

You can also overwrite these values in each @JsonResponse annotation.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\ToJsonResponse;

/**
 * Simple controller method
 *
 * @ToJsonResponse(
 *      status = 403,
 *      headers = {
 *          "User-Agent": "Googlebot/2.1"
 *      }
 * )
 */
public function indexAction(User $user, Address $address)
{
    return array(
        'This is my response'
    );
}

If an Exception is returned the response status is set by default to 500 and the Exception message is returned as response.

STATUS 500 Internal server error

{
    message : 'Exception message'
}

In case we use a HttpExceptionInterface the use the exception status code as status code. In case we launch this exception

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

...

return new NotFoundHttpException('Resource not found');

We'll receive this response

STATUS 404 Not Found

{
    message : 'Resource not found'
}

If the exception is being launched on an annotation (e.g. Entity annotation) remember to add the JsonResponse annotation at the beginning or at least before any annotation that could cause an exception.

If multiple @Mmoreram\JsonResponse are defined in same action, last instance will overwrite previous. Anyway just one instance should be defined.

@Log

Log annotation allows you to log any plain message before or after controller action execution

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Log;

/**
 * Simple controller method
 *
 * @Log("Executing index Action")
 */
public function indexAction()
{
}

You can define the level of the message. You can define default one if none is specified overriding it in your config.yml file.

controller_extra:
    log:
        default_level: warning

Every Annotation instance can overwrite this value using level field.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Log;

/**
 * Simple controller method
 *
 * @Log(
 *      value   = "Executing index Action",
 *      level   = @Log::LVL_WARNING
 * )
 */
public function indexAction()
{
}

Several levels can be used, as defined in [Psr\Log\LoggerInterface][6] interface

  • @Mmoreram\Log::LVL_EMERG
  • @Mmoreram\Log::LVL_CRIT
  • @Mmoreram\Log::LVL_ERR
  • @Mmoreram\Log::LVL_WARN
  • @Mmoreram\Log::LVL_NOTICE
  • @Mmoreram\Log::LVL_INFO
  • @Mmoreram\Log::LVL_DEBUG
  • @Mmoreram\Log::LVL_LOG

You can also define the execution of the log. You can define default one if none is specified overriding it in your config.yml file.

controller_extra:
    log:
        default_execute: pre

Every Annotation instance can overwrite this value using level field.

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Log;

/**
 * Simple controller method
 *
 * @Log(
 *      value   = "Executing index Action",
 *      execute = @Log::EXEC_POST
 * )
 */
public function indexAction()
{
}

Several executions can be used,

  • @Mmoreram\Log::EXEC_PRE - Logged before controller execution
  • @Mmoreram\Log::EXEC_POST - Logged after controller execution
  • @Mmoreram\Log::EXEC_BOTH - Logged both

@Get

The Get annotation allows you to get any parameter from the request query string.

For a GET request like:

GET /my-page?foo=bar HTTP/1.1

You can can simply get the foo var using the GET annotation

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Get;

/**
 * Simple controller method
 *
 * @Get(
 *     path = "foo"
 * )
 */
public function indexAction($foo)
{
    // Use the foo var
}

You can also customize the var name and the default value in case the var is not sent on the query string.

For a GET request like:

GET /my-page HTTP/1.1

And this annotation

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Get;

/**
 * Simple controller method
 *
 * @Get(
 *     path = "foo",
 *     name = "varName",
 *     default = 'bar',
 * )
 */
public function indexAction($varName)
{
    // This would print 'bar'
    echo $varName;
}

@Post

The Post annotation allows you to get any parameter from the post request body.

For a POST request like:

POST /my-page HTTP/1.1
foo=bar

You can can simply get the foo var using the POST annotation

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Post;

/**
 * Simple controller method
 *
 * @Post(
 *     path = "foo"
 * )
 */
public function indexAction($foo)
{
    // Use the foo var
}

You can also customize the var name and the default value in case the var is not sent on the query string.

For a POST request like:

POST /my-page HTTP/1.1

And this annotation

<?php

use Mmoreram\ControllerExtraBundle\Annotation\Post;

/**
 * Simple controller method
 *
 * @Post(
 *     path = "foo",
 *     name = "varName",
 *     default = 'bar',
 * )
 */
public function indexAction($varName)
{
    // This would print 'bar'
    echo $varName;
}

Custom annotations

Using this bundle you can now create, in a very easy way, your own controller annotation.

Annotation

The annotation object. You need to define the fields your custom annotation will contain. Must extends Mmoreram\ControllerExtraBundle\Annotation\Annotation abstract class.

<?php

namespace My\Bundle\Annotation;

use Mmoreram\ControllerExtraBundle\Annotation\Annotation;

/**
 * Entity annotation driver
 *
 * @Annotation
 * @Target({"METHOD"})
 */
final class MyCustomAnnotation extends Annotation
{
    /**
     * @var string
     *
     * Dummy field
     */
    public $field;
    
    /**
     * Get Dummy field
     *
     * @return string Dummy field
     */
    public function getField()
    {
        return $this->field;
    }
}

Resolver

Once you have defined your own annotation, you have to resolve how this annotation works in a controller. You can manage this using a Resolver. Must extend Mmoreram\ControllerExtraBundle\Resolver\AnnotationResolver; abstract class.

<?php

namespace My\Bundle\Resolver;

use Symfony\Component\HttpFoundation\Request;

use Mmoreram\ControllerExtraBundle\Resolver\AnnotationResolver;
use Mmoreram\ControllerExtraBundle\Annotation\Annotation;

/**
 * MyCustomAnnotation Resolver
 */
class MyCustomAnnotationResolver extends AnnotationResolver
{
    /**
     * Specific annotation evaluation.
     *
     * This method must be implemented in every single EventListener
     * with specific logic
     *
     * All method code will executed only if specific active flag is true
     *
     * @param Request          $request
     * @param Annotation       $annotation
     * @param ReflectionMethod $method
     */
    public function evaluateAnnotation(
        Request $request,
        Annotation $annotation,
        ReflectionMethod $method
    )
    {
        /**
         * You can now manage your annotation.
         * You can access to its fields using public methods.
         * 
         * Annotation fields can be public and can be acceded directly,
         * but is better for testing to use getters; they can be mocked.
         */
        $field = $annotation->getField();
        
        /**
         * You can also access to existing method parameters.
         * 
         * Available parameters are:
         * 
         * # ParamConverter parameters ( See `resolver_priority` config value )
         * # All method defined parameters, included Request object if is set.
         */
        $entity = $request->attributes->get('entity');
        
        /**
         * And you can now place new elements in the controller action.
         * In this example we are creating new method parameter
         * called $myNewField with some value
         */
        $request->attributes->set(
            'myNewField',
            new $field()
        );
        
        return $this;
    }

}

This class will be defined as a service, so this method is computed just before executing current controller. You can also subscribe to some kernel events and do whatever you need to do ( You can check Mmoreram\ControllerExtraBundle\Resolver\LogAnnotationResolver for some examples.

Definition

Once Resolver is done, we need to define our service as an Annotation Resolver. We will use a custom tag.

parameters:
    #
    # Resolvers
    #
    my.bundle.resolver.my_custom_annotation_resolver.class: My\Bundle\Resolver\MyCustomAnnotationResolver

services:
    #
    # Resolvers
    #
    my.bundle.resolver.my_custom_annotation_resolver:
        class: %my.bundle.resolver.my_custom_annotation_resolver.class%
        tags:
            - { name: controller_extra.annotation }

Registration

We need to register our annotation inside our application. We can just do it in the boot() method of bundle.php file.

<?php

namespace My\Bundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Doctrine\Common\Annotations\AnnotationRegistry;

/**
 * MyBundle
 */
class ControllerExtraBundle extends Bundle
{

    /**
     * Boots the Bundle.
     */
    public function boot()
    {
        $kernel = $this->container->get('kernel');

        AnnotationRegistry::registerFile($kernel
            ->locateResource("@MyBundle/Annotation/MyCustomAnnotation.php")
        );
    }
}

Et voilà! We can now use our custom Annotation in our project controllers.


Download Details:

Author: mmoreram
Source Code: https://github.com/mmoreram/ControllerExtraBundle

License: MIT license

#symfony #php 

I am Developer

1616903742

Form Validation using jQuery in PHP

Simple contact form submits in PHP MySQL with jQuery validation. In this tutorial, you will learn how to create a contact form in PHP, and how to submit form data into the MySQL database with jQuery validation.

This tutorial helps you step by step for creating or submit a contact forms in PHP MySQL DB with jQuery validation. And you can use this form for your business queries. The good thing is you can use this contact form in your web application too.

Contact Form Validation using jQuery in PHP

Just follow the few below steps and easily create and submit contacct form in PHP MySQL with jquery validation.

  • Step 1 - Create Table in Database
  • Step 2 - Create a Database Connection File
  • Step 3 - Create Contact Form in PHP

https://www.tutsmake.com/php-contact-form-with-jquery-validation-example/

#jquery validation in php registration form #simple jquery form validation example in php #jquery validation in php form