Search code examples
phpsymfonyfosrestbundle

Symfony 3 + FOS REST Bundle: Normalize values before validation


I'm working on a FOS REST API. In the underlying models I'd like to be able to define Constraints representing the form appropriate for the datastore, for example, a US Phone Number should be exactly 10 digits.

/**
 * @var string
 *
 * @Assert\NotBlank(message="Phone is required.")
 * @Assert\Regex(message="Exactly 10 digits are required.",  pattern="/^\d{10}$/")
 */
private $phone;

On the other hand I'd like to be able to accept liberal values, for example a phone number formatted as:

{
    "phone": "603-988-6521"
}

The ideal way to implement this would be to have some type of "conversion" or "normalization" phase where select fields could be converted to all digits etc. prior to validation.

What would be the best way to accomplish this in the FOST REST paradigm and Symfony 3?


Solution

  • It turns out that this is very simple. You can do any type of normalization needed in the actual setters of your model. You just need to configure JMS Serializer to use setters rather than using property reflection. Example with annotations:

    /**
     * @var string
     *
     * @JMS\Accessor(getter="getPhone", setter="setPhone")
     * @Assert\Regex(message="Exactly 10 digits are required.",  pattern="/^\d{10}$/")
     */
    private $phone;
    
    /**
     * @param string
     */
    public function setPhone($phone)
    {
        if ($phone === null) {
            $this->phone = null;
            return;
        }
    
        $this->phone = preg_replace('/[^0-9]/', '', $phone);
    }