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 ), 57 array( 58 getNS($INPUT->post->str('id')), 59 $INPUT->post->str('id'), 60 $_SERVER['REMOTE_USER'] 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 $json = new JSON(); 90 echo $json->encode( 91 array( 92 'message' => $lang['uploadsucc'], 93 'id' => $result 94 ) 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 // store in temporary file 111 $this->tempdir = io_mktmpdir(); 112 if(!$this->tempdir) $this->fail(500); 113 $this->tempfile = $this->tempdir.'/'.md5($data); 114 if(!io_saveFile($this->tempfile, $data)) $this->fail(500); 115 return $this->tempfile; 116 } 117 118 /** 119 * remove temporary file and directory 120 */ 121 private function clean(){ 122 if($this->tempfile && file_exists($this->tempfile)) @unlink($this->tempfile); 123 if($this->tempdir && is_dir($this->tempdir)) @rmdir($this->tempdir); 124 $this->tempfile = ''; 125 $this->tempdir = ''; 126 } 127 128 /** 129 * End the execution with a HTTP error code 130 * 131 * Calls clean 132 * 133 * @param int $status HTTP status code 134 * @param string $text 135 */ 136 private function fail($status, $text=''){ 137 $this->clean(); 138 http_status($status, $text); 139 exit; 140 } 141} 142 143// vim:ts=4:sw=4:et: 144