get_validated_value( $prop_type, $value ); return $this->resolve_item( $value, null, $prop_type ); } public function resolve( array $schema, array $props ): array { $resolved = []; foreach ( $schema as $key => $prop_type ) { if ( ! ( $prop_type instanceof Prop_Type ) ) { continue; } $prop_value = $props[ $key ] ?? null; $actual_value = $this->get_validated_value( $prop_type, $prop_value ); $transformed = $this->resolve_item( $actual_value, $key, $prop_type ); if ( Multi_Props::is( $transformed ) ) { $resolved = array_merge( $resolved, Multi_Props::get_value( $transformed ) ); continue; } $resolved[ $key ] = $transformed; } return $resolved; } protected function resolve_item( $value, $key, Prop_Type $prop_type, int $depth = 0 ) { if ( null === $value ) { return null; } if ( ! $this->is_transformable( $value ) ) { return $this->sanitize_html_prop_value( $value, $prop_type ); } if ( $depth >= self::TRANSFORM_DEPTH_LIMIT ) { return null; } if ( isset( $value['disabled'] ) && true === $value['disabled'] ) { return null; } $transformed = $this->transform( $value, $key, $prop_type ); return $this->resolve_item( $transformed, $key, $prop_type, $depth + 1 ); } private function get_validated_value( Prop_Type $prop_type, $prop_value ) { $default = $prop_type->get_default() ?? null; if ( null === $prop_value ) { return $default; } if ( ! Dynamic_Prop_Type::is_dynamic_prop_value( $prop_value ) ) { return $prop_value; } $tag_name = $prop_value['value']['name'] ?? null; $tag = Plugin::$instance->dynamic_tags->get_tag_info( $tag_name ); return ! $tag ? $default : $prop_value; } private function sanitize_html_prop_value( $value, Prop_Type $prop_type ) { if ( ! is_string( $value ) || ! $this->requires_html_sanitization( $prop_type ) ) { return $value; } return Html_Prop_Type::sanitize_allowed_html( $value ); } private function requires_html_sanitization( Prop_Type $prop_type ): bool { if ( $prop_type instanceof Html_Prop_Type ) { return true; } if ( $prop_type instanceof Union_Prop_Type ) { foreach ( $prop_type->get_prop_types() as $variant ) { if ( $this->requires_html_sanitization( $variant ) ) { return true; } } } return false; } }