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 ), 63 $filename 64 ); 65 $filename = strftime($filename); 66 $filename .= '.'.$mimetypes[$type]; 67 $filename = cleanID($filename); 68 69 // check ACLs 70 $auth = auth_quickaclcheck($filename); 71 if($auth < AUTH_UPLOAD) $this->fail(403, $lang['uploadfail']); 72 73 // do the actual saving 74 $result = media_save( 75 array( 76 'name' => $tempname, 77 'mime' => $type, 78 'ext' => $mimetypes[$type] 79 ), 80 $filename, 81 false, 82 $auth, 83 'copy' 84 ); 85 if(is_array($result)) $this->fail(500, $result[0]); 86 87 //Still here? We had a successful upload 88 $this->clean(); 89 header('Content-Type: application/json'); 90 $json = new JSON(); 91 echo $json->encode( 92 array( 93 'message' => $lang['uploadsucc'], 94 'id' => $result 95 ) 96 ); 97 98 $event->preventDefault(); 99 $event->stopPropagation(); 100 } 101 102 /** 103 * Create a temporary file from the given data 104 * 105 * exits if an error occurs 106 * 107 * @param $data 108 * @return string 109 */ 110 private function storetemp($data){ 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 if($this->tempfile && file_exists($this->tempfile)) @unlink($this->tempfile); 124 if($this->tempdir && is_dir($this->tempdir)) @rmdir($this->tempdir); 125 $this->tempfile = ''; 126 $this->tempdir = ''; 127 } 128 129 /** 130 * End the execution with a HTTP error code 131 * 132 * Calls clean 133 * 134 * @param int $status HTTP status code 135 * @param string $text 136 */ 137 private function fail($status, $text=''){ 138 $this->clean(); 139 http_status($status, $text); 140 exit; 141 } 142} 143 144// vim:ts=4:sw=4:et: 145