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: * Guesses the mime type with the binary "file" (only available on *nix)
19: *
20: * @author Bernhard Schussek <bschussek@gmail.com>
21: */
22: class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
23: {
24: private $cmd;
25:
26: /**
27: * Constructor.
28: *
29: * The $cmd pattern must contain a "%s" string that will be replaced
30: * with the file name to guess.
31: *
32: * The command output must start with the mime type of the file.
33: *
34: * @param string $cmd The command to run to get the mime type of a file
35: */
36: public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
37: {
38: $this->cmd = $cmd;
39: }
40:
41: /**
42: * Returns whether this guesser is supported on the current OS
43: *
44: * @return Boolean
45: */
46: public static function isSupported()
47: {
48: return !defined('PHP_WINDOWS_VERSION_BUILD') && function_exists('passthru') && function_exists('escapeshellarg');
49: }
50:
51: /**
52: * {@inheritdoc}
53: */
54: public function guess($path)
55: {
56: if (!is_file($path)) {
57: throw new FileNotFoundException($path);
58: }
59:
60: if (!is_readable($path)) {
61: throw new AccessDeniedException($path);
62: }
63:
64: if (!self::isSupported()) {
65: return null;
66: }
67:
68: ob_start();
69:
70: // need to use --mime instead of -i. see #6641
71: passthru(sprintf($this->cmd, escapeshellarg($path)), $return);
72: if ($return > 0) {
73: ob_end_clean();
74:
75: return null;
76: }
77:
78: $type = trim(ob_get_clean());
79:
80: if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
81: // it's not a type, but an error message
82: return null;
83: }
84:
85: return $match[1];
86: }
87: }
88: