@@ -83,6 +83,20 @@ class OptionsResolver implements Options
83
83
*/
84
84
private $ allowedTypes = array ();
85
85
86
+ /**
87
+ * A list of accepted types for all options.
88
+ *
89
+ * @var array
90
+ */
91
+ private $ allowedTypesForAll = array ();
92
+
93
+ /**
94
+ * Whether to normalize undefined options.
95
+ *
96
+ * @var array
97
+ */
98
+ private $ allowExtraOptions = false ;
99
+
86
100
/**
87
101
* A list of closures for evaluating lazy options.
88
102
*
@@ -721,6 +735,71 @@ public function addAllowedTypes($option, $allowedTypes)
721
735
return $ this ;
722
736
}
723
737
738
+ /**
739
+ * Adds allowed types for one or more options.
740
+ *
741
+ * If a nested option name is passed it will apply to all nested options.
742
+ *
743
+ * Any type for which a corresponding is_<type>() function exists is
744
+ * acceptable. Additionally, fully-qualified class or interface names may
745
+ * be passed.
746
+ *
747
+ * @param string|string[]|int $optionNames One or more option names
748
+ * or Options::ALL
749
+ * @param string|string[] $allowedTypes One or more accepted types
750
+ * @param bool $replace Whether to replace previous
751
+ * value
752
+ * @param int $nested Whether this method is recursive
753
+ * for nested options which is the
754
+ * default. Pass Options::NONE to
755
+ * change it.
756
+ *
757
+ * @return OptionsResolver This instance
758
+ *
759
+ * @throws UndefinedOptionsException If an option is undefined
760
+ * @throws AccessException If called from a lazy option or normalizer
761
+ */
762
+ public function addAllowedTypesForAll ($ optionNames , $ allowedTypes , $ replace = false , $ nested = Options::ALL )
763
+ {
764
+ if ($ this ->locked ) {
765
+ throw new AccessException ('Allowed types cannot be added from a lazy option or normalizer. ' );
766
+ }
767
+
768
+ if (Options::ALL === $ optionNames ) {
769
+ $ this ->allowedTypesForAll = array_merge ($ this ->allowedTypesForAll , $ allowedTypes );
770
+
771
+ if (Options::NONE === $ nested ) {
772
+ return $ this ;
773
+ }
774
+
775
+ $ optionNames = $ this ->getNestedOptions ();
776
+ }
777
+
778
+ foreach ((array ) $ optionNames as $ option ) {
779
+ if ($ this ->isNested ($ option ) && Options::ALL === $ nested ) {
780
+ $ this ->nested [$ option ]->addAllowedTypesForAll (Options::ALL , $ allowedTypes , $ replace );
781
+ } else {
782
+ if ($ replace ) {
783
+ $ this ->setAllowedTypes ($ option , $ allowedTypes );
784
+ } else {
785
+ $ this ->addAllowedTypes ($ option , $ allowedTypes );
786
+ }
787
+ }
788
+ }
789
+
790
+ return $ this ;
791
+ }
792
+
793
+ /**
794
+ * Defines if undefined options should be resolved.
795
+ *
796
+ * @param bool $allow Whether to resolve undefined options
797
+ */
798
+ public function doAllowExtraOptions ($ allow = true )
799
+ {
800
+ $ this ->allowExtraOptions = $ allow ;
801
+ }
802
+
724
803
/**
725
804
* Removes the option with the given name.
726
805
*
@@ -809,7 +888,7 @@ public function resolve(array $options = array())
809
888
// Make sure that no unknown options are passed
810
889
$ diff = array_diff_key ($ options , $ clone ->defined );
811
890
812
- if (count ($ diff ) > 0 ) {
891
+ if (count ($ diff ) > 0 && false === $ this -> allowExtraOptions ) {
813
892
ksort ($ clone ->defined );
814
893
ksort ($ diff );
815
894
@@ -935,10 +1014,13 @@ public function offsetGet($option)
935
1014
}
936
1015
937
1016
// Validate the type of the resolved option
938
- if (isset ($ this ->allowedTypes [$ option ])) {
1017
+ if (isset ($ this ->allowedTypes [$ option ]) || ( $ this -> allowedTypesForAll && false === $ this -> isNested ( $ option )) ) {
939
1018
$ valid = false ;
940
1019
941
- foreach ($ this ->allowedTypes [$ option ] as $ type ) {
1020
+ $ allowedTypes = isset ($ this ->allowedTypes [$ option ]) ? $ this ->allowedTypes [$ option ] : array ();
1021
+ $ allowedTypes = array_unique (array_merge ($ allowedTypes , $ this ->allowedTypesForAll ));
1022
+
1023
+ foreach ($ allowedTypes as $ type ) {
942
1024
$ type = isset (self ::$ typeAliases [$ type ]) ? self ::$ typeAliases [$ type ] : $ type ;
943
1025
944
1026
if (function_exists ($ isFunction = 'is_ ' .$ type )) {
0 commit comments