xref: /plugin/imgpaste/action.php (revision b7afd893650edb0351982b7805c736f0ca880746)
1<?php
2/**
3 * DokuWiki Plugin imgpaste (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <gohr@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12if(!defined('DOKU_LF')) define('DOKU_LF', "\n");
13if(!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
14if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
15
16require_once DOKU_PLUGIN . 'action.php';
17
18class action_plugin_imgpaste extends DokuWiki_Action_Plugin {
19
20    private $tempdir  = '';
21    private $tempfile = '';
22
23    public function register(Doku_Event_Handler $controller) {
24
25        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
26
27    }
28
29    public function handle_ajax_call_unknown(Doku_Event &$event, $param) {
30        if($event->data != 'plugin_imgpaste') return;
31        global $lang;
32
33        // get data
34        global $INPUT;
35        $data = $INPUT->post->str('data');
36        list($type, $data) = explode(';', $data);
37        if(!$data) $this->fail(400, $this->getLang('e_nodata'));
38
39        // process data encoding
40        $type = strtolower(substr($type, 5)); // strip 'data:' prefix
41        $data = substr($data, 7); // strip 'base64,' prefix
42        $data = base64_decode($data);
43
44        // check for supported mime type
45        $mimetypes = array_flip(getMimeTypes());
46        if(!isset($mimetypes[$type])) $this->fail(415, $lang['uploadwrong']);
47
48        // prepare file names
49        $tempname = $this->storetemp($data);
50        $filename = $this->getConf('filename');
51        $filename = str_replace(
52                        array(
53                             '@NS@',
54                             '@ID@',
55                             '@USER@',
56							 '@PAGE@'
57                        ),
58                        array(
59                             getNS($INPUT->post->str('id')),
60                             $INPUT->post->str('id'),
61                             $_SERVER['REMOTE_USER']
62                        ),
63                        $filename
64                    );
65        $filename  = strftime($filename);
66        $filename .= '.'.$mimetypes[$type];
67        $filename = cleanID($filename);
68
69        // check ACLs
70        $auth = auth_quickaclcheck($filename);
71        if($auth < AUTH_UPLOAD) $this->fail(403, $lang['uploadfail']);
72
73        // do the actual saving
74        $result = media_save(
75                    array(
76                         'name' => $tempname,
77                         'mime' => $type,
78                         'ext'  => $mimetypes[$type]
79                    ),
80                    $filename,
81                    false,
82                    $auth,
83                    'copy'
84        );
85        if(is_array($result)) $this->fail(500, $result[0]);
86
87        //Still here? We had a successful upload
88        $this->clean();
89        header('Content-Type: application/json');
90        $json = new JSON();
91        echo $json->encode(
92            array(
93                'message' => $lang['uploadsucc'],
94                'id' => $result
95            )
96        );
97
98        $event->preventDefault();
99        $event->stopPropagation();
100    }
101
102    /**
103     * Create a temporary file from the given data
104     *
105     * exits if an error occurs
106     *
107     * @param $data
108     * @return string
109     */
110    private function storetemp($data){
111        // store in temporary file
112        $this->tempdir  = io_mktmpdir();
113        if(!$this->tempdir) $this->fail(500);
114        $this->tempfile = $this->tempdir.'/'.md5($data);
115        if(!io_saveFile($this->tempfile, $data)) $this->fail(500);
116        return $this->tempfile;
117    }
118
119    /**
120     * remove temporary file and directory
121     */
122    private function clean(){
123        if($this->tempfile && file_exists($this->tempfile)) @unlink($this->tempfile);
124        if($this->tempdir && is_dir($this->tempdir)) @rmdir($this->tempdir);
125        $this->tempfile = '';
126        $this->tempdir = '';
127    }
128
129    /**
130     * End the execution with a HTTP error code
131     *
132     * Calls clean
133     *
134     * @param int $status HTTP status code
135     * @param string $text
136     */
137    private function fail($status, $text=''){
138        $this->clean();
139        http_status($status, $text);
140        exit;
141    }
142}
143
144// vim:ts=4:sw=4:et:
145