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