3 namespace Drupal\Core\File\MimeType;
5 use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
6 use Symfony\Component\DependencyInjection\ContainerInterface;
7 use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser as SymfonyMimeTypeGuesser;
8 use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
11 * Defines a MIME type guesser that also supports stream wrapper paths.
13 class MimeTypeGuesser implements MimeTypeGuesserInterface {
16 * An array of arrays of registered guessers keyed by priority.
20 protected $guessers = [];
23 * Holds the array of guessers sorted by priority.
25 * If this is NULL a rebuild will be triggered.
27 * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface[]
29 * @see \Drupal\Core\File\MimeType\MimeTypeGuesser::addGuesser()
30 * @see \Drupal\Core\File\MimeType\MimeTypeGuesser::sortGuessers()
32 protected $sortedGuessers = NULL;
35 * The stream wrapper manager.
37 * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
39 protected $streamWrapperManager;
42 * Constructs a MimeTypeGuesser object.
44 * @param StreamWrapperManagerInterface $stream_wrapper_manager
45 * The stream wrapper manager.
47 public function __construct(StreamWrapperManagerInterface $stream_wrapper_manager) {
48 $this->streamWrapperManager = $stream_wrapper_manager;
54 public function guess($path) {
55 if ($wrapper = $this->streamWrapperManager->getViaUri($path)) {
56 // Get the real path from the stream wrapper, if available. Files stored
57 // in remote file systems will not have one.
58 $real_path = $wrapper->realpath();
59 if ($real_path !== FALSE) {
64 if ($this->sortedGuessers === NULL) {
65 // Sort is not triggered yet.
66 $this->sortedGuessers = $this->sortGuessers();
69 foreach ($this->sortedGuessers as $guesser) {
70 $mime_type = $guesser->guess($path);
71 if ($mime_type !== NULL) {
78 * Appends a MIME type guesser to the guessers chain.
80 * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $guesser
81 * The guesser to be appended.
82 * @param int $priority
83 * The priority of the guesser being added.
87 public function addGuesser(MimeTypeGuesserInterface $guesser, $priority = 0) {
88 $this->guessers[$priority][] = $guesser;
89 // Mark sorted guessers for rebuild.
90 $this->sortedGuessers = NULL;
95 * Sorts guessers according to priority.
97 * @return \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface[]
98 * A sorted array of MIME type guesser objects.
100 protected function sortGuessers() {
102 krsort($this->guessers);
104 foreach ($this->guessers as $guesser) {
105 $sorted = array_merge($sorted, $guesser);
111 * A helper function to register with Symfony's singleton MIME type guesser.
113 * Symfony's default mimetype guessers have dependencies on PHP's fileinfo
114 * extension or being able to run the system command file. Drupal's guesser
115 * does not have these dependencies.
117 * @see \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser
119 public static function registerWithSymfonyGuesser(ContainerInterface $container) {
120 // Reset state, so we do not store more and more services during test runs.
121 SymfonyMimeTypeGuesser::reset();
122 $singleton = SymfonyMimeTypeGuesser::getInstance();
123 $singleton->register($container->get('file.mime_type.guesser'));