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 '@PAGE@' 57 ), 58 array( 59 getNS($INPUT->post->str('id')), 60 $INPUT->post->str('id'), 61 $_SERVER['REMOTE_USER'], 62 noNS($INPUT->post->str('id')) 63 ), 64 $filename 65 ); 66 $filename = strftime($filename); 67 $filename .= '.'.$mimetypes[$type]; 68 $filename = cleanID($filename); 69 70 // check ACLs 71 $auth = auth_quickaclcheck($filename); 72 if($auth < AUTH_UPLOAD) $this->fail(403, $lang['uploadfail']); 73 74 // do the actual saving 75 $result = media_save( 76 array( 77 'name' => $tempname, 78 'mime' => $type, 79 'ext' => $mimetypes[$type] 80 ), 81 $filename, 82 false, 83 $auth, 84 'copy' 85 ); 86 if(is_array($result)) $this->fail(500, $result[0]); 87 88 //Still here? We had a successful upload 89 $this->clean(); 90 header('Content-Type: application/json'); 91 $json = new JSON(); 92 echo $json->encode( 93 array( 94 'message' => $lang['uploadsucc'], 95 'id' => $result 96 ) 97 ); 98 99 $event->preventDefault(); 100 $event->stopPropagation(); 101 } 102 103 /** 104 * Create a temporary file from the given data 105 * 106 * exits if an error occurs 107 * 108 * @param $data 109 * @return string 110 */ 111 private function storetemp($data){ 112 // store in temporary file 113 $this->tempdir = io_mktmpdir(); 114 if(!$this->tempdir) $this->fail(500); 115 $this->tempfile = $this->tempdir.'/'.md5($data); 116 if(!io_saveFile($this->tempfile, $data)) $this->fail(500); 117 return $this->tempfile; 118 } 119 120 /** 121 * remove temporary file and directory 122 */ 123 private function clean(){ 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 $this->clean(); 140 http_status($status, $text); 141 exit; 142 } 143} 144 145// vim:ts=4:sw=4:et: 146