1: <?php
2:
3: /*
4: * This file is part of the Symfony package.
5: *
6: * (c) Fabien Potencier <fabien@symfony.com>
7: *
8: * For the full copyright and license information, please view the LICENSE
9: * file that was distributed with this source code.
10: */
11:
12: namespace Symfony\Component\HttpFoundation\File\MimeType;
13:
14: use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
15: use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
16:
17: /**
18: * A singleton mime type guesser.
19: *
20: * By default, all mime type guessers provided by the framework are installed
21: * (if available on the current OS/PHP setup). You can register custom
22: * guessers by calling the register() method on the singleton instance.
23: *
24: * <code>
25: * $guesser = MimeTypeGuesser::getInstance();
26: * $guesser->register(new MyCustomMimeTypeGuesser());
27: * </code>
28: *
29: * The last registered guesser is preferred over previously registered ones.
30: *
31: * @author Bernhard Schussek <bschussek@gmail.com>
32: */
33: class MimeTypeGuesser implements MimeTypeGuesserInterface
34: {
35: /**
36: * The singleton instance
37: *
38: * @var MimeTypeGuesser
39: */
40: private static $instance = null;
41:
42: /**
43: * All registered MimeTypeGuesserInterface instances
44: *
45: * @var array
46: */
47: protected $guessers = array();
48:
49: /**
50: * Returns the singleton instance
51: *
52: * @return MimeTypeGuesser
53: */
54: public static function getInstance()
55: {
56: if (null === self::$instance) {
57: self::$instance = new self();
58: }
59:
60: return self::$instance;
61: }
62:
63: /**
64: * Registers all natively provided mime type guessers
65: */
66: private function __construct()
67: {
68: if (FileBinaryMimeTypeGuesser::isSupported()) {
69: $this->register(new FileBinaryMimeTypeGuesser());
70: }
71:
72: if (FileinfoMimeTypeGuesser::isSupported()) {
73: $this->register(new FileinfoMimeTypeGuesser());
74: }
75: }
76:
77: /**
78: * Registers a new mime type guesser
79: *
80: * When guessing, this guesser is preferred over previously registered ones.
81: *
82: * @param MimeTypeGuesserInterface $guesser
83: */
84: public function register(MimeTypeGuesserInterface $guesser)
85: {
86: array_unshift($this->guessers, $guesser);
87: }
88:
89: /**
90: * Tries to guess the mime type of the given file
91: *
92: * The file is passed to each registered mime type guesser in reverse order
93: * of their registration (last registered is queried first). Once a guesser
94: * returns a value that is not NULL, this method terminates and returns the
95: * value.
96: *
97: * @param string $path The path to the file
98: *
99: * @return string The mime type or NULL, if none could be guessed
100: *
101: * @throws \LogicException
102: * @throws FileNotFoundException
103: * @throws AccessDeniedException
104: */
105: public function guess($path)
106: {
107: if (!is_file($path)) {
108: throw new FileNotFoundException($path);
109: }
110:
111: if (!is_readable($path)) {
112: throw new AccessDeniedException($path);
113: }
114:
115: if (!$this->guessers) {
116: throw new \LogicException('Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)');
117: }
118:
119: foreach ($this->guessers as $guesser) {
120: if (null !== $mimeType = $guesser->guess($path)) {
121: return $mimeType;
122: }
123: }
124: }
125: }
126: