Disabling deduping on specific form element

Created on 23 August 2024, 3 months ago

Problem/Motivation

I'd like to disable deduping on file elements when I create my own forms or via form_alter.

Steps to reproduce

Create a form that includes a managed_file element. There is no way to disable deduping because filehash_file_validate ends up being called,

Proposed resolution

Just like a managed_file field widget accepts to configure deduping settings, allow the form element itself to configure the same.

✨ Feature request
Status

Active

Version

2.0

Component

Code

Created by

πŸ‡¨πŸ‡¦Canada infojunkie Vancouver

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @infojunkie
  • Status changed to Postponed: needs info 3 months ago
  • πŸ‡ΊπŸ‡ΈUnited States mfb San Francisco

    New features won't be added to the 2.x branch - can you try this on the 3.x branch?

    The 3.x has a new API - filehash_file_validate() no longer exists.

    You should be able to add/remove the FileHashDedupe validator from a form's array of upload validators.

  • πŸ‡¨πŸ‡¦Canada infojunkie Vancouver

    Our massive project is not ready to move beyond Drupal 9.x at the moment. When it is, I will provide updates here.

  • πŸ‡ΊπŸ‡ΈUnited States mfb San Francisco

    Well, in that case, at the very least, a developer should be able to implement their own File Hash validation in a custom module, which they can enable or disable as required.

    The validation feature built-in to File Hash module is, in my humble opinion, a proof-of-concept for developers (as mentioned on the project page β†’ ), since a real-world site will probably need a better user experience and more features (for example, automatically re-using the existing file rather than simply rejecting the file upload).

  • πŸ‡¨πŸ‡¦Canada infojunkie Vancouver

    Now that we've upgraded the site to Drupal 10.x, I am back to this issue.

    I'll provide more details:

    We are building a form that extends ConfirmFormBase and that adds an element of type managed_file via buildForm(). This element has a single entry #upload_validators to validate the file extension.

    A filehash violation is triggered when we upload a duplicate file, and that's what we want to suppress - as a special case, because all other file uploads should prevent duplication.

    Using hook_form_alter(), I verified that the element does NOT include a FileHashDedupe entry in its #upload_validators list.

    I also found that the violation comes from FileValidationSubscriber::onFileValidation which provides no obvious way to ignore the duplicate validation for this specific case.

    At this point, I am unsure how to prevent the duplication check from applying to this particular form element.

  • πŸ‡ΊπŸ‡ΈUnited States mfb San Francisco

    @infojunkie: Would you be able to either share a module that reproduces this issue, or write a failing test for this case?

  • πŸ‡ΊπŸ‡ΈUnited States mfb San Francisco

    Here is some code that might work for you in a hook_form_alter():

      $listener = function ($event) {
        foreach ($event->violations as $key => $value) {
          if ($value->getConstraint() instanceof Drupal\filehash\Plugin\Validation\Constraint\FileHashDedupe) {
            $event->violations->remove($key);
          }
        }
      };
      Drupal::service('event_dispatcher')->addListener(Drupal\file\Validation\FileValidationEvent::class, $listener, -1); 

    (Let me know if this does or doesn't work for your issue)

  • πŸ‡¨πŸ‡¦Canada infojunkie Vancouver

    Thanks, I tried your suggestion.

    It works for the following sequence of steps:
    - Select a file that's already been uploaded
    => The file is not rejected and appears in the file input

    But it fails the second time:
    - Click "Remove" button on the file input that was uploaded above
    - Re-select the same file
    => The file is rejected as duplicate

    This is probably due to the file upload happening through ajax and thus skipping the hook_form_alter the second time.

    I don't think this approach would be stable in the general case: For example, what happens if we have multiple file uploads in the form and only one needs to be ignored?

    In my opinion, the most ergonomic approach would be to explicitly add an attribute to the form element that says "Skip this file deduplication". I don't have time to work on this right now but I might revisit it in the future.

  • πŸ‡ΊπŸ‡ΈUnited States mfb San Francisco

    Well, we already allow the dedupe validator to be added to form fields on demand, i.e. explicitly add an attribute to the form element that says "Enable file deduplication"

    The site-wide dedupe setting, on the other hand, doesn't have anything to do with forms. It's a file validator for all new files.

    So I'd recommend not enabling that setting if you don't want it always on. Use the form-field specific dedupe validation instead.

    But, if you insist on hacking that setting to be disable-able, I would say your custom module should add the event subscriber to all requests (not just via form alter), and disable the dedupe constraint based on some aspect of the file entity (such as a unique path, or whatever else might be available).

    It would also seem reasonable for core to start adding more context to file validation events, so that custom event subscribers have more to work with, but I didn't look into if/how that would be possible.

  • πŸ‡¨πŸ‡¦Canada infojunkie Vancouver

    So I'd recommend not enabling that setting if you don't want it always on.
    Use the form-field specific dedupe validation instead.

    Thanks, that's what I will do going forward. It's bit more work than disabling deduping in a single form field, but it certainly beats hacking into the event subscription core!

  • πŸ‡ΊπŸ‡ΈUnited States mfb San Francisco

    Setting to fixed as I don't think there's more to do here.

  • Status changed to Fixed 10 days ago
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024