@@ -42,6 +42,9 @@ class FilterAddressField extends InterfaceField {
4242 * L2TP client.
4343 * @param bool $allow_pppoe Allow this field's value to be `pppoe`. This is used to indicate the address is any
4444 * PPPoE client.
45+ * @param bool $internal_direct If `true`, this field's value will be written as a direct value instead of
46+ * an array. This is useful for fields that need the same validation as this Field, but do not store their
47+ * values as the usual filter address array.
4548 * @param bool $allow_empty If `true`, empty strings will be allowed by this field.
4649 * @param bool $allow_null If `true`, null values will be allowed by this field.
4750 * @param array $interface_query Assigns query parameters to limit which interfaces should be accepted by this
@@ -102,6 +105,7 @@ class FilterAddressField extends InterfaceField {
102105 public bool $ allow_self = true ,
103106 public bool $ allow_l2tp = true ,
104107 public bool $ allow_pppoe = true ,
108+ public bool $ internal_direct = false ,
105109 bool $ allow_empty = false ,
106110 bool $ allow_null = false ,
107111 array $ interface_query = [],
@@ -290,12 +294,12 @@ class FilterAddressField extends InterfaceField {
290294 $ if_ip_modifier_set = false ;
291295
292296 # When `any` is set, additional parameters are irrelevant. Set the `any` internal value and return it.
293- if ($ representation_value === 'any ' ) {
297+ if ($ representation_value === 'any ' and ! $ this -> internal_direct ) {
294298 return ['any ' => true ];
295299 }
296300
297301 # Remove the prefixed invert character (!) and set its internal value if present
298- if (str_starts_with ($ representation_value , self ::INVERT_PREFIX )) {
302+ if (str_starts_with ($ representation_value , self ::INVERT_PREFIX ) and ! $ this -> internal_direct ) {
299303 $ representation_value = substr ($ representation_value , 1 );
300304 $ internal_value ['not ' ] = true ;
301305 }
@@ -306,6 +310,11 @@ class FilterAddressField extends InterfaceField {
306310 $ if_ip_modifier_set = true ;
307311 }
308312
313+ # If this value has internal direct set, we can return it directly
314+ if ($ this ->internal_direct ) {
315+ return $ if_ip_modifier_set ? $ representation_value . 'ip ' : $ representation_value ;
316+ }
317+
309318 # Assign the `address` internal value for individual IP values, subnets, and aliases
310319 if ($ this ->has_label ('is_ipaddr ' ) or $ this ->has_label ('is_subnet ' ) or $ this ->has_label ('is_alias ' )) {
311320 $ internal_value [$ this ->internal_value_key ] = $ representation_value ;
@@ -331,6 +340,15 @@ class FilterAddressField extends InterfaceField {
331340 # Assign a variable to use when piecing back together our representation value
332341 $ representation_value = '' ;
333342
343+ # If this is a direct internal value, just check for the :ip modifier and return the value directly
344+ if ($ this ->internal_direct ) {
345+ # If the value ends with `ip`, append the `:ip` modifier to the representation value
346+ if (str_ends_with ($ internal_value , 'ip ' )) {
347+ return substr ($ internal_value , 0 , -2 ) . ':ip ' ;
348+ }
349+ return $ internal_value ;
350+ }
351+
334352 # If the `any` flag is set, the representation value has to be `any`
335353 if (isset ($ internal_value ['any ' ])) {
336354 return 'any ' ;
0 commit comments