Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1af23c9

Browse filesBrowse files
ycerutofabpot
authored andcommitted
[OptionsResolver] Trigger deprecation only if the option is used
1 parent 0acf9e1 commit 1af23c9
Copy full SHA for 1af23c9

File tree

3 files changed

+131
-19
lines changed
Filter options

3 files changed

+131
-19
lines changed

‎src/Symfony/Component/OptionsResolver/Options.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/OptionsResolver/Options.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*
1717
* @author Bernhard Schussek <bschussek@gmail.com>
1818
* @author Tobias Schultze <http://tobion.de>
19+
*
20+
* @method mixed offsetGet(string $option, bool $triggerDeprecation = true)
1921
*/
2022
interface Options extends \ArrayAccess, \Countable
2123
{

‎src/Symfony/Component/OptionsResolver/OptionsResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/OptionsResolver/OptionsResolver.php
+17-3Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ class OptionsResolver implements Options
8888
*/
8989
private $deprecated = array();
9090

91+
/**
92+
* The list of options provided by the user.
93+
*/
94+
private $given = array();
95+
9196
/**
9297
* Whether the instance is locked for reading.
9398
*
@@ -744,6 +749,7 @@ public function resolve(array $options = array())
744749

745750
// Override options set by the user
746751
foreach ($options as $option => $value) {
752+
$clone->given[$option] = true;
747753
$clone->defaults[$option] = $value;
748754
unset($clone->resolved[$option], $clone->lazy[$option]);
749755
}
@@ -772,7 +778,8 @@ public function resolve(array $options = array())
772778
/**
773779
* Returns the resolved value of an option.
774780
*
775-
* @param string $option The option name
781+
* @param string $option The option name
782+
* @param bool $triggerDeprecation Whether to trigger the deprecation or not (true by default)
776783
*
777784
* @return mixed The option value
778785
*
@@ -784,14 +791,20 @@ public function resolve(array $options = array())
784791
* @throws OptionDefinitionException If there is a cyclic dependency between
785792
* lazy options and/or normalizers
786793
*/
787-
public function offsetGet($option)
794+
public function offsetGet($option/*, bool $triggerDeprecation = true*/)
788795
{
789796
if (!$this->locked) {
790797
throw new AccessException('Array access is only supported within closures of lazy options and normalizers.');
791798
}
792799

800+
$triggerDeprecation = 1 === \func_num_args() || \func_get_arg(1);
801+
793802
// Shortcut for resolved options
794803
if (array_key_exists($option, $this->resolved)) {
804+
if ($triggerDeprecation && isset($this->deprecated[$option]) && \is_string($this->deprecated[$option])) {
805+
@trigger_error(strtr($this->deprecated[$option], array('%name%' => $option)), E_USER_DEPRECATED);
806+
}
807+
795808
return $this->resolved[$option];
796809
}
797810

@@ -920,7 +933,8 @@ public function offsetGet($option)
920933
}
921934

922935
// Check whether the option is deprecated
923-
if (isset($this->deprecated[$option])) {
936+
// and it is provided by the user or is being called from a lazy evaluation
937+
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || ($this->calling && \is_string($this->deprecated[$option])))) {
924938
$deprecationMessage = $this->deprecated[$option];
925939

926940
if ($deprecationMessage instanceof \Closure) {

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php
+112-16Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -491,12 +491,12 @@ public function testSetDeprecatedFailsIfInvalidDeprecationMessageType()
491491
public function testLazyDeprecationFailsIfInvalidDeprecationMessageType()
492492
{
493493
$this->resolver
494-
->setDefault('foo', true)
494+
->setDefined('foo')
495495
->setDeprecated('foo', function (Options $options, $value) {
496496
return false;
497497
})
498498
;
499-
$this->resolver->resolve();
499+
$this->resolver->resolve(array('foo' => null));
500500
}
501501

502502
/**
@@ -506,16 +506,15 @@ public function testLazyDeprecationFailsIfInvalidDeprecationMessageType()
506506
public function testFailsIfCyclicDependencyBetweenDeprecation()
507507
{
508508
$this->resolver
509-
->setDefault('foo', null)
510-
->setDefault('bar', null)
509+
->setDefined(array('foo', 'bar'))
511510
->setDeprecated('foo', function (Options $options, $value) {
512511
$options['bar'];
513512
})
514513
->setDeprecated('bar', function (Options $options, $value) {
515514
$options['foo'];
516515
})
517516
;
518-
$this->resolver->resolve();
517+
$this->resolver->resolve(array('foo' => null, 'bar' => null));
519518
}
520519

521520
public function testIsDeprecated()
@@ -539,10 +538,15 @@ public function testIsNotDeprecatedIfEmptyString()
539538
/**
540539
* @dataProvider provideDeprecationData
541540
*/
542-
public function testDeprecationMessages(\Closure $configureOptions, array $options, ?array $expectedError)
541+
public function testDeprecationMessages(\Closure $configureOptions, array $options, ?array $expectedError, int $expectedCount)
543542
{
543+
$count = 0;
544544
error_clear_last();
545-
set_error_handler(function () { return false; });
545+
set_error_handler(function () use (&$count) {
546+
++$count;
547+
548+
return false;
549+
});
546550
$e = error_reporting(0);
547551

548552
$configureOptions($this->resolver);
@@ -555,6 +559,7 @@ public function testDeprecationMessages(\Closure $configureOptions, array $optio
555559
unset($lastError['file'], $lastError['line']);
556560

557561
$this->assertSame($expectedError, $lastError);
562+
$this->assertSame($expectedCount, $count);
558563
}
559564

560565
public function provideDeprecationData()
@@ -571,6 +576,7 @@ function (OptionsResolver $resolver) {
571576
'type' => E_USER_DEPRECATED,
572577
'message' => 'The option "foo" is deprecated.',
573578
),
579+
1,
574580
);
575581

576582
yield 'It deprecates an option with custom message' => array(
@@ -588,20 +594,27 @@ function (OptionsResolver $resolver) {
588594
'type' => E_USER_DEPRECATED,
589595
'message' => 'The option "foo" is deprecated, use "bar" option instead.',
590596
),
597+
2,
591598
);
592599

593-
yield 'It deprecates a missing option with default value' => array(
600+
yield 'It deprecates an option evaluated in another definition' => array(
594601
function (OptionsResolver $resolver) {
602+
// defined by superclass
595603
$resolver
596-
->setDefaults(array('foo' => null, 'bar' => null))
604+
->setDefault('foo', null)
597605
->setDeprecated('foo')
598606
;
607+
// defined by subclass
608+
$resolver->setDefault('bar', function (Options $options) {
609+
return $options['foo']; // It triggers a deprecation
610+
});
599611
},
600-
array('bar' => 'baz'),
612+
array(),
601613
array(
602614
'type' => E_USER_DEPRECATED,
603615
'message' => 'The option "foo" is deprecated.',
604616
),
617+
1,
605618
);
606619

607620
yield 'It deprecates allowed type and value' => array(
@@ -623,20 +636,46 @@ function (OptionsResolver $resolver) {
623636
'type' => E_USER_DEPRECATED,
624637
'message' => 'Passing an instance of "stdClass" to option "foo" is deprecated, pass its FQCN instead.',
625638
),
639+
1,
626640
);
627641

628-
yield 'It ignores deprecation for missing option without default value' => array(
642+
yield 'It triggers a deprecation based on the value only if option is provided by the user' => array(
629643
function (OptionsResolver $resolver) {
630644
$resolver
631-
->setDefined(array('foo', 'bar'))
632-
->setDeprecated('foo')
645+
->setDefined('foo')
646+
->setAllowedTypes('foo', array('null', 'bool'))
647+
->setDeprecated('foo', function (Options $options, $value) {
648+
if (!\is_bool($value)) {
649+
return 'Passing a value different than true or false is deprecated.';
650+
}
651+
652+
return '';
653+
})
654+
->setDefault('baz', null)
655+
->setAllowedTypes('baz', array('null', 'int'))
656+
->setDeprecated('baz', function (Options $options, $value) {
657+
if (!\is_int($value)) {
658+
return 'Not passing an integer is deprecated.';
659+
}
660+
661+
return '';
662+
})
663+
->setDefault('bar', function (Options $options) {
664+
$options['baz']; // It does not triggers a deprecation
665+
666+
return $options['foo']; // It does not triggers a deprecation
667+
})
633668
;
634669
},
635-
array('bar' => 'baz'),
636-
null,
670+
array('foo' => null), // It triggers a deprecation
671+
array(
672+
'type' => E_USER_DEPRECATED,
673+
'message' => 'Passing a value different than true or false is deprecated.',
674+
),
675+
1,
637676
);
638677

639-
yield 'It ignores deprecation if closure returns an empty string' => array(
678+
yield 'It ignores a deprecation if closure returns an empty string' => array(
640679
function (OptionsResolver $resolver) {
641680
$resolver
642681
->setDefault('foo', null)
@@ -647,6 +686,7 @@ function (OptionsResolver $resolver) {
647686
},
648687
array('foo' => Bar::class),
649688
null,
689+
0,
650690
);
651691

652692
yield 'It deprecates value depending on other option value' => array(
@@ -668,6 +708,62 @@ function (OptionsResolver $resolver) {
668708
'type' => E_USER_DEPRECATED,
669709
'message' => 'Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.',
670710
),
711+
1,
712+
);
713+
714+
yield 'It triggers a deprecation for each evaluation' => array(
715+
function (OptionsResolver $resolver) {
716+
$resolver
717+
// defined by superclass
718+
->setDefined('foo')
719+
->setDeprecated('foo')
720+
// defined by subclass
721+
->setDefault('bar', function (Options $options) {
722+
return $options['foo']; // It triggers a deprecation
723+
})
724+
->setNormalizer('bar', function (Options $options, $value) {
725+
$options['foo']; // It triggers a deprecation
726+
$options['foo']; // It triggers a deprecation
727+
728+
return $value;
729+
})
730+
;
731+
},
732+
array('foo' => 'baz'), // It triggers a deprecation
733+
array(
734+
'type' => E_USER_DEPRECATED,
735+
'message' => 'The option "foo" is deprecated.',
736+
),
737+
4,
738+
);
739+
740+
yield 'It ignores a deprecation if no option is provided by the user' => array(
741+
function (OptionsResolver $resolver) {
742+
$resolver
743+
->setDefined('foo')
744+
->setDefault('bar', null)
745+
->setDeprecated('foo')
746+
->setDeprecated('bar')
747+
;
748+
},
749+
array(),
750+
null,
751+
0,
752+
);
753+
754+
yield 'It explicitly ignores a depreciation' => array(
755+
function (OptionsResolver $resolver) {
756+
$resolver
757+
->setDefault('foo', null)
758+
->setDeprecated('foo')
759+
->setDefault('bar', function (Options $options) {
760+
return $options->offsetGet('foo', false);
761+
})
762+
;
763+
},
764+
array(),
765+
null,
766+
0,
671767
);
672768
}
673769

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.