Dynamic/Types/AttachmentType.php
public function build(FormBuilderInterface $builder, FormField $field, $locale, $options)
    {
        $type = FileType::class;
        $options['mapped'] = false;
        $allConstraints = [];

        // Mime Types Filter.
        $mimeTypes = [];

        $translation = $field->getTranslation($locale);
        if (is_array($translation->getOption('type'))) {
            foreach ($translation->getOption('type') as $attachmentType) {
                $mimeTypes[] = $attachmentType . '/*';
            }
        }

        $options['attr']['accept'] = implode(',', $mimeTypes);

        // File Constraint.
        if ($translation->getOption('type') === ['image']) {
            $fileConstraint = new Image();
        } else {
            $fileConstraint = new File(['mimeTypes' => $mimeTypes]);
        }

        $allConstraints[] = $fileConstraint;

        // Required for Files.
        if ($field->getRequired()) {
            $allConstraints[] = new NotBlank();
        }

        // File Constraint.
        $options['constraints'][] = new All(['constraints' => $allConstraints]);

        // Max File Constraint.
        if ($fileMax = (int) $translation->getOption('max')) {
            $options['constraints'][] = new Count([
                'max' => $fileMax,
            ]);

            $options['attr']['max'] = $fileMax;
        }

        $options['multiple'] = true;
        $builder->add($field->getKey(), $type, $options);
    }
public function build(FormBuilderInterface $builder, FormField $field, $locale, $options)
    {
        $type = FileType::class;
        $options['mapped'] = false;
        $allConstraints = [];

        // Mime Types Filter.
        $mimeTypes = [];

        $translation = $field->getTranslation($locale);
        if (is_array($translation->getOption('type'))) {
            foreach ($translation->getOption('type') as $attachmentType) {
                $mimeTypes[] = $attachmentType . '/*';
            }
        }

        $options['attr']['accept'] = implode(',', $mimeTypes);

        // File Constraint.
        if ($translation->getOption('type') === ['image']) {
            $fileConstraint = new Image();
        } else {
            $fileConstraint = new File(['mimeTypes' => $mimeTypes]);
        }

        $allConstraints[] = $fileConstraint;

        // Required for Files.
        if ($field->getRequired()) {
            $allConstraints[] = new NotBlank();
        }

        // File Constraint.
        $options['constraints'][] = new All(['constraints' => $allConstraints]);

        // Max File Constraint.
        if ($fileMax = (int) $translation->getOption('max')) {
            $options['constraints'][] = new Count([
                'max' => $fileMax,
            ]);

            $options['attr']['max'] = $fileMax;
        }

        $options['multiple'] = true;
        $builder->add($field->getKey(), $type, $options);
    }
{@inheritdoc}