Separate MIME type mapping from ExtensionMimeTypeGuesser

Created on 29 July 2014, over 10 years ago
Updated 30 January 2023, almost 2 years ago

Problem/Motivation

With #1921558: Convert file_get_mimetype() to use Symfony MimeTypeGuessers โ†’ , the function file_mimetype_mapping() was removed. The mapping was placed as a protected property of the ExtensionMimeTypeGuesser class, as its main purpose was for the guesser to use it. But there are cases when the mapping, or just the list of MIME types, should be used in itself, outside the context of guessing. For instance, a form in the File entity module should present known MIME types for the user.

Proposed resolution

Move the default mapping to a new service and class, Drupal\Core\File\MimeType\MimeTypeMapper, with getter/setter methods.

Introduce an alterMapping() method which invokes the mimetype alter hook upon service instantiation to allow modules to play with MIME type<->extension mapping.

Change the ExtensionMimeTypeGuesser class to use the new mapper; deprecate its ::setMapping method.

Deprecate the file_mimetype_mapping alter hook.

Add tests.

Add tests.

Remaining tasks

Commit

User interface changes

None

API changes

A new service file.mime_type.mapper.

Beta phase evaluation

<!--Uncomment the relevant rows for the issue. -->
๐Ÿ› Bug report
Status

Needs work

Version

10.1 โœจ

Component
File systemย  โ†’

Last updated 2 days ago

Created by

๐Ÿ‡ธ๐Ÿ‡ชSweden Arla

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

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Merge request !3166Resolve #2311679 "Separate mime type" โ†’ (Open) created by bhanu951
  • The Needs Review Queue Bot โ†’ tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

    Consult the Drupal Contributor Guide โ†’ to find step-by-step guides for working with issues.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    kim.pepper โ†’ made their first commit to this issueโ€™s fork.

  • Pipeline finished with Failed
    about 2 months ago
    Total: 236s
    #296581
  • Pipeline finished with Failed
    about 2 months ago
    Total: 259s
    #296583
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    kim.pepper โ†’ changed the visibility of the branch 11.x to hidden.

  • Pipeline finished with Failed
    about 2 months ago
    Total: 520s
    #296763
  • Pipeline finished with Failed
    about 2 months ago
    Total: 594s
    #297556
  • Pipeline finished with Failed
    about 2 months ago
    Total: 202s
    #297614
  • Pipeline finished with Failed
    about 2 months ago
    Total: 588s
    #297618
  • Pipeline finished with Success
    about 2 months ago
    Total: 904s
    #297631
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Did a fair amount of cleanup on this issue.

    • ExtensionMimeTypeGuesser is now using the MimeTypeMapper
    • Removed the getMapping() method which was temporary anyway and refactored tests to not call it
    • Split up tests and moved them to the Drupal\KernelTests\Core\File\MimeType namespace to make the namespace under lib/
    • Handle NULL returned from ExtensionMimeTypeGuesser::guessMimeType()
    • Updated the changes to the default map that went in since this was last worked on a year ago
    • Added typehints
    • Added more dependency injection
    • Fixed linting errors
    • Updated the deprecation message to refer to 11.1.0 and 12.0.0
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Why not allow contrib modules to call getMapping() so they can arbitrarily alter the mapping?

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Can't already alter the mapping with the alter hook?

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Also different mapping implementations could use different data structures, so what gets returned from getMapping() could be different.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Well I'm looking at how to still allow File MIME module โ†’ work without using the deprecated hook_file_mimetype_mapping_alter(). It looks like the new alter hook doesn't allow contrib module to get the mapping so it can make various changes, and then apply it via setMapping().

    And different data structures? Well that would make it even more difficult for a contrib module to alter the mapping, lol sigh. I confess to not actually following this issue.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    function hook_mimetype_alter(?MimeTypeMapperInterface $mime_type_mapper = NULL) gives you the ability to add/remove/update mappings by using the API interface rather than the raw data structure, which is better IMO.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Yes I see know it's possible to call addMapping(). But I'd have to iterate through and make hundreds of method calls (if someone configures File MIME module to parse their /etc/mime.types file), with an array_search() in each one, so it just seems slower, that's all. And I'd have to double check there is no behavior change from how it worked previously.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Realized I was being lazy and I should benchmark it. So, I found that implementing the new hook in File MIME module (configured to add all the MIME types from the /etc/mime.types file) adds about 10 milliseconds of execution time. This is probably fine for those cases where the hook is invoked during file uploads - such requests are going to be extremely slow regardless - but not ideal for other pages where the hook might be invoked (e.g. managing display of an entity with a file field). Admittedly, File MIME module doesn't have very many installs (and more installs of the Drupal 7 branch than the current branch).

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    #128 Thinking about this further, we should probably remove setMapping() to hide the underlying data structure. Projects like https://www.drupal.org/project/sophron โ†’ that use the https://github.com/FileEye/MimeMap library have a different data structure.

    #129 hmm. Shouldn't that hook only get fired on container build? It should be cached after that.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @kim.pepper no, there is nothing caching the map, whether in the container or otherwise. Both the old and new alter hooks run whenever the map is used.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    Projects like https://www.drupal.org/project/sophron โ†’ that use the https://github.com/FileEye/MimeMap library have a different data structure.

    I looked at Sophron module, and it has a totally different mechanism for allowing other modules to alter its mapping - it dispatches an event. I guess you are saying that a future version of Sophron module could start invoking this alter hook?

  • Pipeline finished with Success
    about 1 month ago
    Total: 666s
    #299507
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    #131 I don't think that's right.

      file.mime_type.mapper:
        class: Drupal\Core\File\MimeType\MimeTypeMapper
        calls:
          - [alterMapping, ['@module_handler']]
    

    The hook gets fired when this service is created.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    alterMapping is called whenever the file.mime_type.mapper service is created (for example when ExtensionMimeTypeGuesser is constructed). So the alter hook fires on any request that needs to create that service.

    E.g. if a page renders an entity that displays an audio file field, the service is needed and the alter hook fires. But once that entity is cached in the render cache, it will no longer render, and therefore the service won't be created, so the alter hook won't fire. Maybe that is the caching you were referring to, I'm not sure? There are also admin pages where the service is created, and the alter hook fires, without any sort of cache being involved (e.g. managing display of an entity with a file field).

  • Pipeline finished with Failed
    about 1 month ago
    Total: 145s
    #299549
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    #134 Yeah I guess I was talking about the container cache. I misunderstood what you meant by 'Both the old and new alter hooks run whenever the map is used.' thinking you meant when we call guessMimeType() but it's when the service is created.

    I did some more work removing setMapping(). I don't think that's going to cause too many issues.

  • Pipeline finished with Success
    about 1 month ago
    Total: 796s
    #299557
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    I was timing the alter hook on requests where the service is created (e.g. because guessMimeType() was called at least once). Since it's when the service is created, the 10ms slowdown only happens at most once per request.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 114s
    #300408
  • Pipeline finished with Failed
    about 1 month ago
    Total: 531s
    #300409
  • Pipeline finished with Failed
    about 1 month ago
    Total: 588s
    #300414
  • Pipeline finished with Failed
    about 1 month ago
    Total: 115s
    #300574
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    I've done a fair bit of rework to replace the new hook with tagged services. I think triggering hooks during container build is a bit of an antipattern, and this approach uses a more symfony native approach.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 552s
    #300596
  • Pipeline finished with Failed
    about 1 month ago
    Total: 1015s
    #300615
  • Pipeline finished with Failed
    about 1 month ago
    Total: 368s
    #300635
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mfb San Francisco

    @kim.pepper I don't understand why you say "triggering hooks during container build" - the hook was triggered when the service was created, i.e. when a request needs to use it for the first time, not when the container is built.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 557s
    #301374
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    the hook was triggered when the service was created

    Fair enough.

    As for the test fail, I have no idea why \Drupal\Tests\block\Functional\BlockCacheTest::testCachePerPage() is failing. It's passing locally for me. Could it be a random fail?

  • Pipeline finished with Failed
    about 1 month ago
    Total: 701s
    #301380
  • Pipeline finished with Failed
    about 1 month ago
    Total: 1068s
    #301427
  • Pipeline finished with Failed
    about 1 month ago
    Total: 451s
    #301447
  • Pipeline finished with Success
    about 1 month ago
    Total: 414s
    #301460
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Found the source of the test fails was a deprecation warning on the legacy hook_file_mimetype_mapping_alter() in file_test.module. We already test this in file_deprecated_test.module so I removed it.

    Ready for reviews again!

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly mondrake ๐Ÿ‡ฎ๐Ÿ‡น

    mondrake โ†’ changed the visibility of the branch 2311679-separate-mime-type to hidden.

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly mondrake ๐Ÿ‡ฎ๐Ÿ‡น

    I did a review. I am definitely biased by having developed Sophron, feel free to push back.

    Also, adding a related issue that should be committed before this IMHO

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Thanks for the detailed review @mondrake. Much appreciated. I've responded to all your comments and made changes where I agree. I resolved a few where I did not agree, but feel free to re-open those threads if you disagree.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 122s
    #302045
  • Pipeline finished with Failed
    about 1 month ago
    Total: 589s
    #302046
  • Pipeline finished with Failed
    about 1 month ago
    Total: 632s
    #302496
  • Pipeline finished with Success
    about 1 month ago
    Total: 427s
    #302508
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    I created a POC MR with a FileEye MIME map implementation to check if our interfaces and factory approach works with 3rd party libs.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 132s
    #302541
  • Pipeline finished with Failed
    about 1 month ago
    Total: 106s
    #302542
  • The Needs Review Queue Bot โ†’ tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide โ†’ to find step-by-step guides for working with issues.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Rebased.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 163s
    #305806
  • The Needs Review Queue Bot โ†’ tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide โ†’ to find step-by-step guides for working with issues.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 130s
    #305856
  • Pipeline finished with Failed
    about 1 month ago
    Total: 134s
    #305864
  • Pipeline finished with Success
    about 1 month ago
    Total: 979s
    #305870
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Tests are passing.

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly mondrake ๐Ÿ‡ฎ๐Ÿ‡น

    A bunch of nitpickeries from me. I think this is almost ready, cannot RTBC it though.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 719s
    #308896
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Addressed all feedback. Thanks again.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 570s
    #308902
  • Pipeline finished with Success
    about 1 month ago
    Total: 1063s
    #308910
  • One small deprecation docblock issue with version numbers.

  • Pipeline finished with Canceled
    29 days ago
    Total: 91s
    #313117
  • Pipeline finished with Success
    29 days ago
    Total: 2230s
    #313118
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Thanks. Feedback addressed.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia kim.pepper ๐Ÿ„โ€โ™‚๏ธ๐Ÿ‡ฆ๐Ÿ‡บSydney, Australia

    Added tests and answered question.

  • Pipeline finished with Success
    28 days ago
    Total: 602s
    #314406
  • godotislate โ†’ changed the visibility of the branch 2311679-separate-mime-type-11.x to hidden.

  • godotislate โ†’ changed the visibility of the branch 2311679-separate-mime-type-11.x to active.

  • godotislate โ†’ changed the visibility of the branch 2311679-separate-mime-type-fileeye to hidden.

  • ๐Ÿ‡ฎ๐Ÿ‡นItaly mondrake ๐Ÿ‡ฎ๐Ÿ‡น
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly mondrake ๐Ÿ‡ฎ๐Ÿ‡น

    working on this

  • Pipeline finished with Failed
    20 days ago
    Total: 136s
    #322267
  • Pipeline finished with Failed
    19 days ago
    Total: 692s
    #322288
  • Pipeline finished with Success
    19 days ago
    Total: 2566s
    #322298
  • ๐Ÿ‡ฎ๐Ÿ‡นItaly mondrake ๐Ÿ‡ฎ๐Ÿ‡น

    rerolled

  • Pipeline finished with Failed
    13 days ago
    #328067
  • Pipeline finished with Failed
    13 days ago
    Total: 596s
    #328071
  • Pipeline finished with Failed
    5 days ago
    Total: 737s
    #334844
  • Pipeline finished with Running
    5 days ago
    #334873
Production build 0.71.5 2024