PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, March 9, 2022

[FIXED] How to normalize two related options with OptionsResolver Component

 March 09, 2022     php, symfony     No comments   

Issue

I've the follows situation based on OptionsResolver Component:

  • I have two options: bar and foo, both null by default.
  • bar option accepts B value also.
  • foo option accepts A, B, C, D values also.

Now, when these options are resolved, if foo option is equal to A, bar option must be changed to B, but I need too: if foo option is equal to A or B this must be changed to C.


I tried to implement that but the expected result is wrong:

use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;

$resolver = new OptionsResolver();
$resolver->setDefaults(array(
    'bar' => null,
    'foo' => null,
));
$resolver->setAllowedValues('bar', array(null, 'B'));
$resolver->setAllowedValues('foo', array(null, 'A', 'B', 'C', 'D'));

$resolver->setNormalizer('bar', function (Options $options, $value) {
    if ('A' === $options['foo']) {
        return 'B';
    }

    return $value;
});

$resolver->setNormalizer('foo', function (Options $options, $value) {
    if ('A' === $value || 'B' === $value) {
        $value = 'C';
    }

    return $value;
});

$options = $resolver->resolve(array('foo' => 'A'));

var_dump($options);

this always returns:

array(2) {
  ["foo"] => string(1) "C"
  ["bar"] => NULL  // wrong normalization, expected `B` value.
}

The problem is that 'A' === $options['foo'] statement in bar normalizer calls to foo normalizer ( i.e. $options->offsetGet('foo')) before to complete the condition, so for this test always checks 'A' === 'C' and bar option does not normalized successfully.

How to do it works?


Solution

Well, it's a horrible workaround but it's the code that I implemented finally:

$resolver = new OptionsResolver();
$resolver->setDefaults(array(
    'foo' => null,  // <-- move to top to make sure to normalize first that bar
    'bar' => null,  // for internal use
));
$resolver->setAllowedValues('bar', array(null, 'B'));
$resolver->setAllowedValues('foo', array(null, 'A', 'B', 'C', 'D'));

$bar = null;

$resolver->setNormalizer('foo', function (Options $options, $value) use (&$bar) {
    if ('A' === $value) {
        $bar = 'B';
    }

    if ('A' === $value || 'B' === $value) {
        $value = 'C';
    }

    return $value;
});

$resolver->setNormalizer('bar', function (Options $options, $value) use (&$bar) {
    return $bar;
});

$options = $resolver->resolve(array('foo' => 'A'));


Answered By - yceruto
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing