xref: /plugin/imgpaste/action.php (revision 584f4635cf3ddb15ca366ad61b3368def7a24007)
14df872e4SAndreas Gohr<?php
2832cd161SAndreas 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 */
9832cd161SAndreas Gohrclass action_plugin_imgpaste extends DokuWiki_Action_Plugin
10832cd161SAndreas Gohr{
114df872e4SAndreas Gohr
12*584f4635SAndreas Gohr    protected $tempdir = '';
13*584f4635SAndreas Gohr    protected $tempfile = '';
14*584f4635SAndreas Gohr
15*584f4635SAndreas Gohr    /**
16*584f4635SAndreas Gohr     * Clean up on destruction
17*584f4635SAndreas Gohr     */
18*584f4635SAndreas Gohr    public function __destruct()
19*584f4635SAndreas Gohr    {
20*584f4635SAndreas Gohr        $this->clean();
21*584f4635SAndreas Gohr    }
224df872e4SAndreas Gohr
23832cd161SAndreas Gohr    /** @inheritdoc */
24832cd161SAndreas Gohr    public function register(Doku_Event_Handler $controller)
25832cd161SAndreas Gohr    {
26832cd161SAndreas Gohr        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxUpload');
274df872e4SAndreas Gohr    }
284df872e4SAndreas Gohr
29832cd161SAndreas Gohr    /**
30832cd161SAndreas Gohr     * Creates a new file from the given data URL
31832cd161SAndreas Gohr     *
32832cd161SAndreas Gohr     * @param Doku_Event $event AJAX_CALL_UNKNOWN
33832cd161SAndreas Gohr     */
34832cd161SAndreas Gohr    public function handleAjaxUpload(Doku_Event $event)
35832cd161SAndreas Gohr    {
364df872e4SAndreas Gohr        if ($event->data != 'plugin_imgpaste') return;
374df872e4SAndreas Gohr        global $lang;
384df872e4SAndreas Gohr
394df872e4SAndreas Gohr        // get data
404df872e4SAndreas Gohr        global $INPUT;
414df872e4SAndreas Gohr        $data = $INPUT->post->str('data');
424df872e4SAndreas Gohr        list($type, $data) = explode(';', $data);
434df872e4SAndreas Gohr        if (!$data) $this->fail(400, $this->getLang('e_nodata'));
444df872e4SAndreas Gohr
454df872e4SAndreas Gohr        // process data encoding
464df872e4SAndreas Gohr        $type = strtolower(substr($type, 5)); // strip 'data:' prefix
474df872e4SAndreas Gohr        $data = substr($data, 7); // strip 'base64,' prefix
484df872e4SAndreas Gohr        $data = base64_decode($data);
494df872e4SAndreas Gohr
504df872e4SAndreas Gohr        // check for supported mime type
514df872e4SAndreas Gohr        $mimetypes = array_flip(getMimeTypes());
524df872e4SAndreas Gohr        if (!isset($mimetypes[$type])) $this->fail(415, $lang['uploadwrong']);
534df872e4SAndreas Gohr
544df872e4SAndreas Gohr        // prepare file names
554df872e4SAndreas Gohr        $tempname = $this->storetemp($data);
56*584f4635SAndreas Gohr        $filename = $this->createFileName($INPUT->post->str('id'), $mimetypes[$type], $_SERVER['REMOTE_USER']);
574df872e4SAndreas Gohr
584df872e4SAndreas Gohr        // check ACLs
594df872e4SAndreas Gohr        $auth = auth_quickaclcheck($filename);
604df872e4SAndreas Gohr        if ($auth < AUTH_UPLOAD) $this->fail(403, $lang['uploadfail']);
614df872e4SAndreas Gohr
624df872e4SAndreas Gohr        // do the actual saving
634df872e4SAndreas Gohr        $result = media_save(
64*584f4635SAndreas Gohr            [
654df872e4SAndreas Gohr                'name' => $tempname,
664df872e4SAndreas Gohr                'mime' => $type,
67832cd161SAndreas Gohr                'ext' => $mimetypes[$type],
68*584f4635SAndreas Gohr            ],
694df872e4SAndreas Gohr            $filename,
704df872e4SAndreas Gohr            false,
714df872e4SAndreas Gohr            $auth,
724df872e4SAndreas Gohr            'copy'
734df872e4SAndreas Gohr        );
744df872e4SAndreas Gohr        if (is_array($result)) $this->fail(500, $result[0]);
754df872e4SAndreas Gohr
764df872e4SAndreas Gohr        //Still here? We had a successful upload
774df872e4SAndreas Gohr        $this->clean();
784df872e4SAndreas Gohr        header('Content-Type: application/json');
79832cd161SAndreas Gohr        echo json_encode([
804df872e4SAndreas Gohr            'message' => $lang['uploadsucc'],
81832cd161SAndreas Gohr            'id' => $result,
82832cd161SAndreas Gohr            'mime' => $type,
83832cd161SAndreas Gohr            'ext' => $mimetypes[$type],
84832cd161SAndreas Gohr            'url' => ml($result),
85832cd161SAndreas Gohr        ]);
864df872e4SAndreas Gohr
874df872e4SAndreas Gohr        $event->preventDefault();
884df872e4SAndreas Gohr        $event->stopPropagation();
894df872e4SAndreas Gohr    }
904df872e4SAndreas Gohr
914df872e4SAndreas Gohr    /**
92*584f4635SAndreas Gohr     * Create the filename for the new file
93*584f4635SAndreas Gohr     *
94*584f4635SAndreas Gohr     * @param string $pageid the original page the paste event happend on
95*584f4635SAndreas Gohr     * @param string $ext the extension of the file
96*584f4635SAndreas Gohr     * @param string $user the currently logged in user
97*584f4635SAndreas Gohr     * @return string
98*584f4635SAndreas Gohr     */
99*584f4635SAndreas Gohr    protected function createFileName($pageid, $ext, $user)
100*584f4635SAndreas Gohr    {
101*584f4635SAndreas Gohr        $filename = $this->getConf('filename');
102*584f4635SAndreas Gohr        $filename = str_replace(
103*584f4635SAndreas Gohr            [
104*584f4635SAndreas Gohr                '@NS@',
105*584f4635SAndreas Gohr                '@ID@',
106*584f4635SAndreas Gohr                '@USER@',
107*584f4635SAndreas Gohr                '@PAGE@',
108*584f4635SAndreas Gohr            ],
109*584f4635SAndreas Gohr            [
110*584f4635SAndreas Gohr                getNS($pageid),
111*584f4635SAndreas Gohr                $pageid,
112*584f4635SAndreas Gohr                $user,
113*584f4635SAndreas Gohr                noNS($pageid),
114*584f4635SAndreas Gohr            ],
115*584f4635SAndreas Gohr            $filename
116*584f4635SAndreas Gohr        );
117*584f4635SAndreas Gohr        $filename = strftime($filename);
118*584f4635SAndreas Gohr        $filename .= '.' . $ext;
119*584f4635SAndreas Gohr        return cleanID($filename);
120*584f4635SAndreas Gohr    }
121*584f4635SAndreas Gohr
122*584f4635SAndreas Gohr    /**
1234df872e4SAndreas Gohr     * Create a temporary file from the given data
1244df872e4SAndreas Gohr     *
1254df872e4SAndreas Gohr     * exits if an error occurs
1264df872e4SAndreas Gohr     *
1274df872e4SAndreas Gohr     * @param $data
1284df872e4SAndreas Gohr     * @return string
1294df872e4SAndreas Gohr     */
130*584f4635SAndreas Gohr    protected function storetemp($data)
131832cd161SAndreas Gohr    {
1324df872e4SAndreas Gohr        // store in temporary file
1334df872e4SAndreas Gohr        $this->tempdir = io_mktmpdir();
1344df872e4SAndreas Gohr        if (!$this->tempdir) $this->fail(500);
1354df872e4SAndreas Gohr        $this->tempfile = $this->tempdir . '/' . md5($data);
1364df872e4SAndreas Gohr        if (!io_saveFile($this->tempfile, $data)) $this->fail(500);
1374df872e4SAndreas Gohr        return $this->tempfile;
1384df872e4SAndreas Gohr    }
1394df872e4SAndreas Gohr
1404df872e4SAndreas Gohr    /**
1414df872e4SAndreas Gohr     * remove temporary file and directory
1424df872e4SAndreas Gohr     */
143*584f4635SAndreas Gohr    protected function clean()
144832cd161SAndreas Gohr    {
1454df872e4SAndreas Gohr        if ($this->tempfile && file_exists($this->tempfile)) @unlink($this->tempfile);
1464df872e4SAndreas Gohr        if ($this->tempdir && is_dir($this->tempdir)) @rmdir($this->tempdir);
1474df872e4SAndreas Gohr        $this->tempfile = '';
1484df872e4SAndreas Gohr        $this->tempdir = '';
1494df872e4SAndreas Gohr    }
1504df872e4SAndreas Gohr
1514df872e4SAndreas Gohr    /**
1524df872e4SAndreas Gohr     * End the execution with a HTTP error code
1534df872e4SAndreas Gohr     *
1544df872e4SAndreas Gohr     * Calls clean
1554df872e4SAndreas Gohr     *
1564df872e4SAndreas Gohr     * @param int $status HTTP status code
1574df872e4SAndreas Gohr     * @param string $text
1584df872e4SAndreas Gohr     */
159*584f4635SAndreas Gohr    protected function fail($status, $text = '')
160832cd161SAndreas Gohr    {
1614df872e4SAndreas Gohr        $this->clean();
1624df872e4SAndreas Gohr        http_status($status, $text);
1634df872e4SAndreas Gohr        exit;
1644df872e4SAndreas Gohr    }
165*584f4635SAndreas Gohr
1664df872e4SAndreas Gohr}
167