Problem/Motivation

The SVG Image module currently has an issue with form validation when multiple image fields are present on the same form. When a form contains both a standard image field and an SVG-enabled image field, the validation constraints from one field are incorrectly applied to all fields.
Specifically, the FileIsImage constraint that is automatically added by ImageItem::getUploadValidators() is causing validation errors when uploading SVG files, even though the SVG Image module attempts to remove this validator in the widget's formElement() method. This issue became more prominent in Drupal 10.2+ with the transition to Symfony Constraints for file validation.

Steps to reproduce

  1. Install Drupal 10.2+ with the SVG Image module
  2. Create a content type with two image fields:
  3. Field A: A standard image field that accepts only jpg, png, gif (default settings)
  4. Field B: An image field that has been configured to accept SVG files
  5. Try to create content and upload an SVG file to Field B
  6. Observe that the form validation fails with an error message like "The file is not a valid image"

Proposed resolution

Implement hook_validation_constraint_alter() in the SVG Image module to replace the core FileIsImage constraint with a custom constraint that properly handles SVG files. This approach addresses the root cause of the issue by modifying the validation system at a more fundamental level, rather than trying to remove validators at the widget level.
The custom constraint will check if the file is an SVG file (based on mime type or extension) and skip the image validation for those files, while still applying the standard image validation to non-SVG files.

  • Implement hook_validation_constraint_alter() to replace the core constraint
  • Test with multiple image fields on the same form
  • Test with various Drupal 10.x versions to ensure compatibility

User interface changes

None. This change affects the validation logic but does not modify any user interface elements.

API changes

The module will now use hook_validation_constraint_alter() to replace the core FileIsImage constraint with a custom implementation. This is an internal change that doesn't affect the public API of the module.

Data model changes

None. This change only affects the validation process and does not modify any data structures or storage

Issue fork svg_image-3515345

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jorgik created an issue. See original summary.

mably’s picture

Status: Active » Postponed (maintainer needs more info)

I have followed the steps indicated but have not been able to reproduce the problem.

Though I was on Drupal 11.1. Could it be a Drupal 10 specific issue?

Gitlab-CI shows quite a few PHPCS and PHPStan warnings that should be fixed.

jorgik’s picture

My current setup is 10.4.5, also same issue happens inside paragraphs, when svg_image part of the paragraphs' entity which is part of node

mably’s picture

Could you validate your scenario on a fresh Drupal 10 install?

Looks like you might be in a situation where the validator is not unset like it should.

Substituting our own SVG compatible validator seems like a more sustainable solution though.

jorgik’s picture

Unable to reproduce on 10.3.14, maybe related to focal point that also on the project I have. Anyway, could be useful to have own validator

mably’s picture

Status: Postponed (maintainer needs more info) » Needs review
mably’s picture

Status: Needs review » Reviewed & tested by the community

Nice works, thanks!

Tested successfully.

What is interesting is that it will make this module compatible with Image Widget Crop.

We will only need to add this simple hook to make it work:

/**
 * Implements hook_field_widget_single_element_form_alter().
 */
function svg_image_field_widget_single_element_form_alter(&$element, &$form_state, $context) {
  if ($context['widget'] instanceof ImageWidget && !$context['widget'] instanceof SvgImageWidget) {
    $field_definition = $context['items']->getFieldDefinition();
    $field_settings = $field_definition->getSettings();
    $allowed_extensions = explode(' ', $field_settings['file_extensions']);
    if (in_array('svg', $allowed_extensions)) {
      $extensions = explode(' ', $element['#upload_validators']['FileExtension']['extensions']);
      if (!in_array('svg', $extensions)) {
        $extensions[] = 'svg';
        $element['#upload_validators']['FileExtension']['extensions'] = implode(' ', $extensions);
      }
    }
    $class = '\Drupal\svg_image\Plugin\Field\FieldWidget\SvgImageWidget';
    $element['#process'] = array_merge($element['#process'], [[$class, 'process']]);
  }
}

Will create a separate issue for it.

anybody made their first commit to this issue’s fork.