xref: /plugin/imgpaste/action.php (revision 832cd16116fe537c83226c44e00a234c7389f636)
14df872e4SAndreas Gohr<?php
2*832cd161SAndreas Gohr
34df872e4SAndreas Gohr/**
44df872e4SAndreas Gohr * DokuWiki Plugin imgpaste (Action Component)
54df872e4SAndreas Gohr *
64df872e4SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
74df872e4SAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
84df872e4SAndreas Gohr */
9*832cd161SAndreas Gohrclass action_plugin_imgpaste extends DokuWiki_Action_Plugin
10*832cd161SAndreas Gohr{
114df872e4SAndreas Gohr
124df872e4SAndreas Gohr    private $tempdir = '';
134df872e4SAndreas Gohr    private $tempfile = '';
144df872e4SAndreas Gohr
15*832cd161SAndreas Gohr    /** @inheritdoc */
16*832cd161SAndreas Gohr    public function register(Doku_Event_Handler $controller)
17*832cd161SAndreas Gohr    {
18*832cd161SAndreas Gohr        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxUpload');
194df872e4SAndreas Gohr    }
204df872e4SAndreas Gohr
21*832cd161SAndreas Gohr    /**
22*832cd161SAndreas Gohr     * Creates a new file from the given data URL
23*832cd161SAndreas Gohr     *
24*832cd161SAndreas Gohr     * @param Doku_Event $event AJAX_CALL_UNKNOWN
25*832cd161SAndreas Gohr     */
26*832cd161SAndreas Gohr    public function handleAjaxUpload(Doku_Event $event)
27*832cd161SAndreas Gohr    {
284df872e4SAndreas Gohr        if ($event->data != 'plugin_imgpaste') return;
294df872e4SAndreas Gohr        global $lang;
304df872e4SAndreas Gohr
314df872e4SAndreas Gohr        // get data
324df872e4SAndreas Gohr        global $INPUT;
334df872e4SAndreas Gohr        $data = $INPUT->post->str('data');
344df872e4SAndreas Gohr        list($type, $data) = explode(';', $data);
354df872e4SAndreas Gohr        if (!$data) $this->fail(400, $this->getLang('e_nodata'));
364df872e4SAndreas Gohr
374df872e4SAndreas Gohr        // process data encoding
384df872e4SAndreas Gohr        $type = strtolower(substr($type, 5)); // strip 'data:' prefix
394df872e4SAndreas Gohr        $data = substr($data, 7); // strip 'base64,' prefix
404df872e4SAndreas Gohr        $data = base64_decode($data);
414df872e4SAndreas Gohr
424df872e4SAndreas Gohr        // check for supported mime type
434df872e4SAndreas Gohr        $mimetypes = array_flip(getMimeTypes());
444df872e4SAndreas Gohr        if (!isset($mimetypes[$type])) $this->fail(415, $lang['uploadwrong']);
454df872e4SAndreas Gohr
464df872e4SAndreas Gohr        // prepare file names
474df872e4SAndreas Gohr        $tempname = $this->storetemp($data);
484df872e4SAndreas Gohr        $filename = $this->getConf('filename');
494df872e4SAndreas Gohr        $filename = str_replace(
50*832cd161SAndreas Gohr            [
514df872e4SAndreas Gohr                '@NS@',
524df872e4SAndreas Gohr                '@ID@',
53252b10e0Sfstorck                '@USER@',
54*832cd161SAndreas Gohr                '@PAGE@',
55*832cd161SAndreas Gohr            ],
56*832cd161SAndreas Gohr            [
574df872e4SAndreas Gohr                getNS($INPUT->post->str('id')),
584df872e4SAndreas Gohr                $INPUT->post->str('id'),
59252b10e0Sfstorck                $_SERVER['REMOTE_USER'],
60*832cd161SAndreas Gohr                noNS($INPUT->post->str('id')),
61*832cd161SAndreas Gohr            ],
624df872e4SAndreas Gohr            $filename
634df872e4SAndreas Gohr        );
644df872e4SAndreas Gohr        $filename = strftime($filename);
654df872e4SAndreas Gohr        $filename .= '.' . $mimetypes[$type];
664df872e4SAndreas Gohr        $filename = cleanID($filename);
674df872e4SAndreas Gohr
684df872e4SAndreas Gohr        // check ACLs
694df872e4SAndreas Gohr        $auth = auth_quickaclcheck($filename);
704df872e4SAndreas Gohr        if ($auth < AUTH_UPLOAD) $this->fail(403, $lang['uploadfail']);
714df872e4SAndreas Gohr
724df872e4SAndreas Gohr        // do the actual saving
734df872e4SAndreas Gohr        $result = media_save(
744df872e4SAndreas Gohr            array(
754df872e4SAndreas Gohr                'name' => $tempname,
764df872e4SAndreas Gohr                'mime' => $type,
77*832cd161SAndreas Gohr                'ext' => $mimetypes[$type],
784df872e4SAndreas Gohr            ),
794df872e4SAndreas Gohr            $filename,
804df872e4SAndreas Gohr            false,
814df872e4SAndreas Gohr            $auth,
824df872e4SAndreas Gohr            'copy'
834df872e4SAndreas Gohr        );
844df872e4SAndreas Gohr        if (is_array($result)) $this->fail(500, $result[0]);
854df872e4SAndreas Gohr
864df872e4SAndreas Gohr        //Still here? We had a successful upload
874df872e4SAndreas Gohr        $this->clean();
884df872e4SAndreas Gohr        header('Content-Type: application/json');
89*832cd161SAndreas Gohr        echo json_encode([
904df872e4SAndreas Gohr            'message' => $lang['uploadsucc'],
91*832cd161SAndreas Gohr            'id' => $result,
92*832cd161SAndreas Gohr            'mime' => $type,
93*832cd161SAndreas Gohr            'ext' => $mimetypes[$type],
94*832cd161SAndreas Gohr            'url' => ml($result),
95*832cd161SAndreas Gohr        ]);
964df872e4SAndreas Gohr
974df872e4SAndreas Gohr        $event->preventDefault();
984df872e4SAndreas Gohr        $event->stopPropagation();
994df872e4SAndreas Gohr    }
1004df872e4SAndreas Gohr
1014df872e4SAndreas Gohr    /**
1024df872e4SAndreas Gohr     * Create a temporary file from the given data
1034df872e4SAndreas Gohr     *
1044df872e4SAndreas Gohr     * exits if an error occurs
1054df872e4SAndreas Gohr     *
1064df872e4SAndreas Gohr     * @param $data
1074df872e4SAndreas Gohr     * @return string
1084df872e4SAndreas Gohr     */
109*832cd161SAndreas Gohr    private function storetemp($data)
110*832cd161SAndreas Gohr    {
1114df872e4SAndreas Gohr        // store in temporary file
1124df872e4SAndreas Gohr        $this->tempdir = io_mktmpdir();
1134df872e4SAndreas Gohr        if (!$this->tempdir) $this->fail(500);
1144df872e4SAndreas Gohr        $this->tempfile = $this->tempdir . '/' . md5($data);
1154df872e4SAndreas Gohr        if (!io_saveFile($this->tempfile, $data)) $this->fail(500);
1164df872e4SAndreas Gohr        return $this->tempfile;
1174df872e4SAndreas Gohr    }
1184df872e4SAndreas Gohr
1194df872e4SAndreas Gohr    /**
1204df872e4SAndreas Gohr     * remove temporary file and directory
1214df872e4SAndreas Gohr     */
122*832cd161SAndreas Gohr    private function clean()
123*832cd161SAndreas Gohr    {
1244df872e4SAndreas Gohr        if ($this->tempfile && file_exists($this->tempfile)) @unlink($this->tempfile);
1254df872e4SAndreas Gohr        if ($this->tempdir && is_dir($this->tempdir)) @rmdir($this->tempdir);
1264df872e4SAndreas Gohr        $this->tempfile = '';
1274df872e4SAndreas Gohr        $this->tempdir = '';
1284df872e4SAndreas Gohr    }
1294df872e4SAndreas Gohr
1304df872e4SAndreas Gohr    /**
1314df872e4SAndreas Gohr     * End the execution with a HTTP error code
1324df872e4SAndreas Gohr     *
1334df872e4SAndreas Gohr     * Calls clean
1344df872e4SAndreas Gohr     *
1354df872e4SAndreas Gohr     * @param int $status HTTP status code
1364df872e4SAndreas Gohr     * @param string $text
1374df872e4SAndreas Gohr     */
138*832cd161SAndreas Gohr    private function fail($status, $text = '')
139*832cd161SAndreas Gohr    {
1404df872e4SAndreas Gohr        $this->clean();
1414df872e4SAndreas Gohr        http_status($status, $text);
1424df872e4SAndreas Gohr        exit;
1434df872e4SAndreas Gohr    }
1444df872e4SAndreas Gohr}
145