0

I'm trying to use Zend\Validator to validate objects but I find it hard for a couple of reasons and am now wondering if I'm doing something fundamentally wrong or if the component is just not a good choice to do so…

Ideally I'd like to run

$objectValidator = new ObjectValidator();
$objectValidator->isValid($object);

So in this case I would put (sub-)validators for the objects properties in ObjectValidator's isValid() method for example like this:

public function isValid($value, $context = null)
{
    $propertyValidator = new Zend\Validator\Callback(function($value) {
        return false;
    });
    if (!$propertyValidator->isValid($value)) {
        foreach ($propertyValidator->getMessages() as $code => $message) {
            $this->abstractOptions['messages'][$code] = $message;
        }
        return false;
    }

    return true;
}

The way to merge the messages from the property's validator I've copied from the component's EmailAddress validator that falls back on the Hostname validator.

The trouble starts when I'm using a type of validator twice (e.g. Callback) no matter if on the same property or a different since the messages are merged and I'm loosing information that I'd like to have. I could build a way to manage the messages myself but I'm wondering if there's not a better solution.

I also thought of using Zend\InputFilter instead creating Zend\Inputs for each property that I want to run checks on. This way I certainly get all the messages but it adds a rather annoying task of dismantling the object before I can validate it.

Any input highly appreciated.

pitty.platsch
  • 77
  • 1
  • 13

1 Answers1

0

I would suggest to use the ZF2 InputFilter class as a base for deep validating objects and properties.

You can implement Zend\Stdlib\ArraySerializableInterface interface to solve the "annoying task of dismantling the object" issue with a getArrayCopy method:

<?php

namespace Application\Model;

use Zend\Stdlib\ArraySerializableInterface;

class MyObject implements ArraySerializableInterface
{

   /**
     * Exchange internal values from provided array
     *
     * @param  array $array
     * @return void
     */
    public function exchangeArray(array $array)
    {
        //...Your custom logic to exchange properties with data from an array
    }

    /**
     * Return an array representation of the object
     *
     * @return array
     */
    public function getArrayCopy()
    {
        //...Your custom logic to get array copy of the object for validation
    }
}

Or make a custom hydrator class that does this for you...

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • @pitty.platsch did it work out for you with using the `InputFilter` class and the suggested interface? – Wilt Nov 23 '15 at 07:58
  • I agree. You should use a `Zend\StdLib\Hydrator` to extract data from your object and use a `Zend\InputFilter\InputFilter` to validate that data. Zend's Hydrators already [support different ways](http://framework.zend.com/manual/current/en/modules/zend.stdlib.hydrator.html#available-implementations) to extract data from objects. – Charlie Vieillard Nov 23 '15 at 10:01