Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d531b3

Browse files
committed
Passing Options argument to deprecation closure
1 parent 3e7b029 commit 2d531b3

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

src/Symfony/Component/OptionsResolver/OptionsResolver.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,8 +860,20 @@ public function offsetGet($option)
860860
if (isset($this->deprecated[$option])) {
861861
$deprecationMessage = $this->deprecated[$option];
862862

863-
if ($deprecationMessage instanceof \Closure && !\is_string($deprecationMessage = $deprecationMessage($value))) {
864-
throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", returns an empty string to ignore.', \gettype($deprecationMessage)));
863+
if ($deprecationMessage instanceof \Closure) {
864+
// If the closure is already being called, we have a cyclic dependency
865+
if (isset($this->calling[$option])) {
866+
throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', implode('", "', array_keys($this->calling))));
867+
}
868+
869+
$this->calling[$option] = true;
870+
try {
871+
if (!\is_string($deprecationMessage = $deprecationMessage($this, $value))) {
872+
throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", returns an empty string to ignore.', \gettype($deprecationMessage)));
873+
}
874+
} finally {
875+
unset($this->calling[$option]);
876+
}
865877
}
866878

867879
if ('' !== $deprecationMessage) {

src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public function testGetClosureDeprecationMessage()
215215
{
216216
$resolver = new OptionsResolver();
217217
$resolver->setDefined('foo');
218-
$resolver->setDeprecated('foo', $closure = function ($value) {});
218+
$resolver->setDeprecated('foo', $closure = function (Options $options, $value) {});
219219

220220
$debug = new OptionsResolverIntrospector($resolver);
221221
$this->assertSame($closure, $debug->getDeprecationMessage('foo'));

src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,13 +492,32 @@ public function testLazyDeprecationFailsIfInvalidDeprecationMessageType()
492492
{
493493
$this->resolver
494494
->setDefault('foo', true)
495-
->setDeprecated('foo', function ($value) {
495+
->setDeprecated('foo', function (Options $options, $value) {
496496
return false;
497497
})
498498
;
499499
$this->resolver->resolve();
500500
}
501501

502+
/**
503+
* @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException
504+
* @expectedExceptionMessage The options "foo", "bar" have a cyclic dependency.
505+
*/
506+
public function testFailsIfCyclicDependencyBetweenDeprecation()
507+
{
508+
$this->resolver
509+
->setDefault('foo', null)
510+
->setDefault('bar', null)
511+
->setDeprecated('foo', function (Options $options, $value) {
512+
$options['bar'];
513+
})
514+
->setDeprecated('bar', function (Options $options, $value) {
515+
$options['foo'];
516+
})
517+
;
518+
$this->resolver->resolve();
519+
}
520+
502521
public function testIsDeprecated()
503522
{
504523
$this->resolver
@@ -590,7 +609,7 @@ function (OptionsResolver $resolver) {
590609
$resolver
591610
->setDefault('foo', null)
592611
->setAllowedTypes('foo', array('null', 'string', \stdClass::class))
593-
->setDeprecated('foo', function ($value) {
612+
->setDeprecated('foo', function (Options $options, $value) {
594613
if ($value instanceof \stdClass) {
595614
return sprintf('Passing an instance of "%s" to option "foo" is deprecated, pass its FQCN instead.', \stdClass::class);
596615
}
@@ -621,14 +640,35 @@ function (OptionsResolver $resolver) {
621640
function (OptionsResolver $resolver) {
622641
$resolver
623642
->setDefault('foo', null)
624-
->setDeprecated('foo', function ($value) {
643+
->setDeprecated('foo', function (Options $options, $value) {
625644
return '';
626645
})
627646
;
628647
},
629648
array('foo' => Bar::class),
630649
null,
631650
);
651+
652+
yield 'It deprecates value depending on other option value' => array(
653+
function (OptionsResolver $resolver) {
654+
$resolver
655+
->setDefault('widget', null)
656+
->setDefault('date_format', null)
657+
->setDeprecated('date_format', function (Options $options, $dateFormat) {
658+
if (null !== $dateFormat && 'single_text' === $options['widget']) {
659+
return 'Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.';
660+
}
661+
662+
return '';
663+
})
664+
;
665+
},
666+
array('widget' => 'single_text', 'date_format' => 2),
667+
array(
668+
'type' => E_USER_DEPRECATED,
669+
'message' => 'Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.',
670+
),
671+
);
632672
}
633673

634674
/**

0 commit comments

Comments
 (0)