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

[RFC] Remove array typehint from various classes to allow Traversable, ArrayAccess objects #318

Open
maks-rafalko opened this issue Dec 28, 2016 · 0 comments

Comments

@maks-rafalko
Copy link
Contributor

maks-rafalko commented Dec 28, 2016

Hi,

I would like to add a new great feature, but first of all, I will explain why

Problem

I need to filter those products (lines) from the CSV file where both Stock < 10 AND Price < 20.
The key word here is AND.

So I want to have validators that can validate the array with dependent fields when both conditions must be met.

This is impossible with plain PHP arrays. Simply Symfony Validator can not do it. We can't use Expression or Callback constraints for plain PHP arrays, we can use them only with objects. (see ValidatorFilter to understand limitations of PHP arrays).

Solution

We can replace a plain PHP array with ArrayObject and use it just like a simple array, but additionally we can assign all class-based Constraints to our object and get all the power of Symfony Validator.

Let's have an example of how to correctly filter out those products with this new approach:

class ImportedProductDto extends \ArrayObject
{
    /**
     * @Assert\Callback
     */
    public function validate(ExecutionContextInterface $context, $payload)
    {
        if ($this['stock'] < 10 && $this['price'] < 20) {
            $context->buildViolation('Product has stock less than 10 AND price less than 20!')
                ->atPath('stock')
                ->addViolation();
        }
    }
}

and then in the import command:

...
$converterStep = new ConverterStep();

$converterStep->add(function (array $item) {
    // convert plain PHP array to ArrayObject
    return new ImportedProductDto($item);
});

$stepAggregator->addStep($converterStep);
...

That's it.

So since we extend the built-in ArrayObject, all the rest code works as expected because such objects can be used as arrays: $input['cost']

The only one thing is that we need to remove array typehint (or introduce iterable for PHP7.1+ later) and adopt ValidationFilter to work with this approach.

As a result, we will bring the full power of Class Constraints to this library and still can use plain PHP arrays as well as ArrayAccess objects.

What do you guys think about this RFC?

I look forward to you reply and ready to provide a PR.

@Baachi @ddeboer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant