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