1<?php
2
3namespace Sabre\DAV\Browser;
4
5use Sabre\DAV;
6use Sabre\DAV\Inode;
7use Sabre\DAV\PropFind;
8use Sabre\HTTP\URLUtil;
9
10/**
11 * GuessContentType plugin
12 *
13 * A lot of the built-in File objects just return application/octet-stream
14 * as a content-type by default. This is a problem for some clients, because
15 * they expect a correct contenttype.
16 *
17 * There's really no accurate, fast and portable way to determine the contenttype
18 * so this extension does what the rest of the world does, and guesses it based
19 * on the file extension.
20 *
21 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
22 * @author Evert Pot (http://evertpot.com/)
23 * @license http://sabre.io/license/ Modified BSD License
24 */
25class GuessContentType extends DAV\ServerPlugin {
26
27    /**
28     * List of recognized file extensions
29     *
30     * Feel free to add more
31     *
32     * @var array
33     */
34    public $extensionMap = [
35
36        // images
37        'jpg' => 'image/jpeg',
38        'gif' => 'image/gif',
39        'png' => 'image/png',
40
41        // groupware
42        'ics' => 'text/calendar',
43        'vcf' => 'text/vcard',
44
45        // text
46        'txt' => 'text/plain',
47
48    ];
49
50    /**
51     * Initializes the plugin
52     *
53     * @param DAV\Server $server
54     * @return void
55     */
56    function initialize(DAV\Server $server) {
57
58        // Using a relatively low priority (200) to allow other extensions
59        // to set the content-type first.
60        $server->on('propFind', [$this, 'propFind'], 200);
61
62    }
63
64    /**
65     * Our PROPFIND handler
66     *
67     * Here we set a contenttype, if the node didn't already have one.
68     *
69     * @param PropFind $propFind
70     * @param INode $node
71     * @return void
72     */
73    function propFind(PropFind $propFind, INode $node) {
74
75        $propFind->handle('{DAV:}getcontenttype', function() use ($propFind) {
76
77            list(, $fileName) = URLUtil::splitPath($propFind->getPath());
78            return $this->getContentType($fileName);
79
80        });
81
82    }
83
84    /**
85     * Simple method to return the contenttype
86     *
87     * @param string $fileName
88     * @return string
89     */
90    protected function getContentType($fileName) {
91
92        // Just grabbing the extension
93        $extension = strtolower(substr($fileName, strrpos($fileName, '.') + 1));
94        if (isset($this->extensionMap[$extension])) {
95            return $this->extensionMap[$extension];
96        }
97        return 'application/octet-stream';
98
99    }
100
101}
102