1010use Nette \Schema \Context ;
1111use Nette \Schema \DynamicParameter ;
1212use Nette \Schema \Helpers ;
13+ use Nette \Schema \MergeMode ;
1314use Nette \Schema \Schema ;
1415use function array_key_exists , array_pop , implode , is_array , str_replace , strpos ;
1516
@@ -26,6 +27,7 @@ final class Type implements Schema
2627 private array $ range = [null , null ];
2728 private ?string $ pattern = null ;
2829 private bool $ merge = false ;
30+ private ?MergeMode $ mergeMode = null ;
2931
3032
3133 public function __construct (string $ type )
@@ -57,6 +59,16 @@ public function mergeDefaults(bool $state = true): self
5759 }
5860
5961
62+ /**
63+ * Sets how arrays are combined when merging multiple configurations.
64+ */
65+ public function mergeMode (MergeMode $ mode ): self
66+ {
67+ $ this ->mergeMode = $ mode ;
68+ return $ this ;
69+ }
70+
71+
6072 /**
6173 * Allows the value to be a DynamicParameter, which is recorded for deferred validation.
6274 */
@@ -142,19 +154,19 @@ public function normalize(mixed $value, Context $context): mixed
142154
143155 public function merge (mixed $ value , mixed $ base ): mixed
144156 {
145- if (is_array ($ value ) && isset ($ value [Helpers::PreventMerging])) {
157+ if ($ this -> mergeMode === MergeMode::Replace || ( is_array ($ value ) && isset ($ value [Helpers::PreventMerging]) )) {
146158 unset($ value [Helpers::PreventMerging]);
147159 return $ value ;
148160 }
149161
150- if (is_array ($ value ) && is_array ($ base ) && $ this ->itemsValue ) {
151- $ index = 0 ;
162+ if (is_array ($ value ) && is_array ($ base ) && ( $ this ->itemsValue || $ this -> mergeMode ) ) {
163+ $ index = $ this -> mergeMode === MergeMode::OverwriteKeys ? null : 0 ;
152164 foreach ($ value as $ key => $ val ) {
153165 if ($ key === $ index ) {
154166 $ base [] = $ val ;
155167 $ index ++;
156168 } else {
157- $ base [$ key ] = array_key_exists ($ key , $ base )
169+ $ base [$ key ] = array_key_exists ($ key , $ base ) && $ this -> itemsValue
158170 ? $ this ->itemsValue ->merge ($ val , $ base [$ key ])
159171 : $ val ;
160172 }
0 commit comments