ircmaxell / filterus

A simple filtering library for PHP
454 stars 55 forks source link

Can I achieve optional keys by using a pool of maps? #13

Open halfer opened 6 years ago

halfer commented 6 years ago

I have a validation requirement where an array can look like either of these:

[ 'name' => 'string',
  'from_address' => 'email',
  'from_name' => 'string',
  'subject' => 'string',
  'body_plain' => 'string',
  'to_address' => 'email', ] // Differs just in this key

[ 'name' => 'string',
  'from_address' => 'email',
  'from_name' => 'string',
  'subject' => 'string',
  'body_plain' => 'string',
  'to_address_field' => 'string', ] // Differs just in this key

My strategy is that, since there is no way to specify keys as optional, I could run a map for each one, and accept if either returns true. On that basis, I thought I could use a pool as well.

use Filterus\Filter as F;

$baseValidator = [
    'name' => 'string',
    'from_address' => 'email',
    'from_name' => 'string',
    'subject' => 'string',
    'body_plain' => 'string',
];

// Use a pool of maps, should work?
$eitherValidators = F::pool([
    F::map($baseValidator + ['to_address_field' => 'string', ]),
    F::map($baseValidator + ['to_address' => 'email', ]),
]);

However, this blows up in the Filterus internals:

explode() expects parameter 2 to be string, array given

.../vendor/ircmaxell/filterus/lib/Filterus/Filter.php:98
.../vendor/ircmaxell/filterus/lib/Filterus/Filter.php:52
.../vendor/ircmaxell/filterus/lib/Filterus/Filters/Map.php:21
.../vendor/ircmaxell/filterus/lib/Filterus/Filters/Map.php:45

I'll write a custom validator for now, but would be interested to see how people would solve this.