1<?php
2
3/**
4 * DokuWiki WebDAV Plugin - Media File Type
5 *
6 * @link     https://dokuwiki.org/plugin:webdav
7 * @author   Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
8 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
9 */
10
11namespace dokuwiki\plugin\webdav\core\DAV\Collection\Media;
12
13use dokuwiki\plugin\webdav\core\DAV\AbstractFile;
14use dokuwiki\plugin\webdav\core\Utils;
15use Sabre\DAV\Exception\Forbidden;
16use Sabre\DAV\Exception\UnsupportedMediaType;
17
18class File extends AbstractFile
19{
20    public function delete()
21    {
22        Utils::log('debug', 'Delete media');
23
24        if ($this->info['perm'] < AUTH_DELETE) {
25            throw new Forbidden('You are not allowed to delete this file');
26        }
27
28        $res = media_delete($this->info['id'], null);
29
30        // TODO remove metafile in attic ?
31        //if ($metafile = $this->info['metafile']) {
32        //    @unlink($metafile);
33        //}
34
35        if ($res == DOKU_MEDIA_DELETED) {
36            return true;
37        }
38
39        if ($res == DOKU_MEDIA_INUSE) {
40            throw new Forbidden('Media file in use');
41        }
42    }
43
44    public function put($stream)
45    {
46        global $lang;
47
48        // check ACL permissions
49        if (@file_exists($this->info['path'])) {
50            $perm_needed = AUTH_DELETE;
51        } else {
52            $perm_needed = AUTH_UPLOAD;
53        }
54
55        if ($this->info['perm'] < $perm_needed) {
56            throw new Forbidden('Insufficient Permissions');
57        }
58
59        $overwrite     = file_exists($this->info['path']);
60        $filesize_old  = $overwrite ? filesize($this->info['path']) : 0;
61        $timestamp_old = @filemtime($this->info['path']);
62
63        // get filetype for regexp check
64        $types = array_keys(getMimeTypes());
65        $types = array_map(
66            function ($q) {
67                return preg_quote($q, "/");
68            },
69            $types
70        );
71        $regex = join('|', $types);
72
73        Utils::log('debug', "Allowed files $regex");
74
75        // check valid file type
76        if (!preg_match('/\.(' . $regex . ')$/i', $this->info['path'])) {
77            throw new UnsupportedMediaType($lang['uploadwrong']);
78        }
79
80        io_createNamespace($this->info['id'], 'media');
81
82        if (!Utils::streamWriter($stream, $this->info['path'])) {
83            throw new Forbidden($lang['uploadfail']);
84        }
85
86        // save the original filename
87        io_saveFile($this->info['metafile'], serialize([
88            'filename' => $this->info['filename'],
89        ]));
90
91        $timestamp_new = @filemtime($this->info['path']);
92        $filesize_new  = filesize($this->info['path']);
93        $sizechange    = $filesize_new - $filesize_old;
94
95        if (!file_exists(mediaFN($this->info['id'], $timestamp_old)) && file_exists($this->info['path'])) {
96            // add old revision to the attic if missing
97            media_saveOldRevision($this->info['id']);
98        }
99
100        media_notify($this->info['id'], $this->info['path'], $this->getContentType(), $timestamp_old, $timestamp_new);
101
102        // write entry in media log
103        if ($overwrite) {
104            addMediaLogEntry($timestamp_new, $this->info['id'], DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange);
105        } else {
106            addMediaLogEntry($timestamp_new, $this->info['id'], DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange);
107        }
108
109        // TODO call MEDIA_UPLOAD_FINISH
110    }
111}
112