1212use Nette \Schema \Context ;
1313use Nette \Schema \DynamicParameter ;
1414use Nette \Schema \Helpers ;
15+ use Nette \Schema \MergeMode ;
1516use Nette \Schema \Schema ;
1617use function array_key_exists , array_pop , implode , is_array , str_replace , strpos ;
1718
@@ -28,6 +29,7 @@ final class Type implements Schema
2829 private array $ range = [null , null ];
2930 private ?string $ pattern = null ;
3031 private bool $ merge = false ;
32+ private ?MergeMode $ mergeMode = null ;
3133
3234
3335 public function __construct (string $ type )
@@ -56,6 +58,13 @@ public function mergeDefaults(bool $state = true): self
5658 }
5759
5860
61+ public function mergeMode (MergeMode $ mode ): self
62+ {
63+ $ this ->mergeMode = $ mode ;
64+ return $ this ;
65+ }
66+
67+
5968 public function dynamic (): self
6069 {
6170 $ this ->type = DynamicParameter::class . '| ' . $ this ->type ;
@@ -135,19 +144,19 @@ public function normalize(mixed $value, Context $context): mixed
135144
136145 public function merge (mixed $ value , mixed $ base ): mixed
137146 {
138- if (is_array ($ value ) && isset ($ value [Helpers::PreventMerging])) {
147+ if ($ this -> mergeMode === MergeMode::Replace || ( is_array ($ value ) && isset ($ value [Helpers::PreventMerging]) )) {
139148 unset($ value [Helpers::PreventMerging]);
140149 return $ value ;
141150 }
142151
143- if (is_array ($ value ) && is_array ($ base ) && $ this ->itemsValue ) {
144- $ index = 0 ;
152+ if (is_array ($ value ) && is_array ($ base ) && ( $ this ->itemsValue || $ this -> mergeMode ) ) {
153+ $ index = $ this -> mergeMode === MergeMode::OverwriteKeys ? null : 0 ;
145154 foreach ($ value as $ key => $ val ) {
146155 if ($ key === $ index ) {
147156 $ base [] = $ val ;
148157 $ index ++;
149158 } else {
150- $ base [$ key ] = array_key_exists ($ key , $ base )
159+ $ base [$ key ] = array_key_exists ($ key , $ base ) && $ this -> itemsValue
151160 ? $ this ->itemsValue ->merge ($ val , $ base [$ key ])
152161 : $ val ;
153162 }
0 commit comments