1<?php 2/** 3 * DokuWiki Plugin Gview (Syntax Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Sahara Satoshi <sahara.satoshi@gmail.com> 7 * 8 * @see also:https://docs.google.com/viewer# 9 * Google Docs Viewer Terms of Service 10 * By using this service you acknowledge that you have read and 11 * agreed to the Google Docs Viewer Terms of Service. 12 * 13 * Google Docs Viewer plugin 14 * Shows a online document using Google Docs Viewer Service. 15 * SYNTAX: {{gview [size] [noembed] [noreference] > mediaID|title }} 16 * {{obj:[class] [size] [noembed] [noreference] > mediaID|title }} 17 */ 18 19// must be run within Dokuwiki 20if (!defined('DOKU_INC')) die(); 21if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 22require_once DOKU_PLUGIN.'syntax.php'; 23 24class syntax_plugin_gview extends DokuWiki_Syntax_Plugin { 25 26 // URL of Google Docs Viwer Service 27 const URLgoogleViwer = 'https://docs.google.com/viewer'; 28 29 public function getType() { return 'substition'; } 30 public function getPType() { return 'normal'; } 31 public function getSort() { return 305; } 32 public function connectTo($mode) { 33 $this->Lexer->addSpecialPattern('{{gview.*?>.*?}}',$mode,'plugin_gview'); 34 35 // trick pattern :-) 36 $this->Lexer->addSpecialPattern('{{obj:.*?>.*?}}',$mode,'plugin_gview'); 37 } 38 39 40 /** 41 * Resolve media URLs 42 * Create Media Link from DokuWiki media id considering $conf['userewrite'] value. 43 * @see function ml() in inc/common.php 44 * 45 * @param (string) $linkId mediaId 46 * @return (string) URL that does NOT contain DOKU_URL 47 */ 48 private function _resolveMediaUrl($linkId = '') { 49 global $ACT, $ID, $conf; 50 51 // external URLs are always direct without rewriting 52 if(preg_match('#^https?://#i', $linkId)) { return $linkId; } 53 54 resolve_mediaid(getNS($ID), $linkId, $exists); 55 $linkId = idfilter($linkId); 56 if (!$exists && ($ACT=='preview')) { 57 msg($this->getPluginName().': media file not exists: '.$linkId, -1); 58 return false; 59 } 60 // check access control 61 if (!media_ispublic($linkId) && ($ACT=='preview')) { 62 msg($this->getPluginName().': '.$linkId.' is NOT public!', 2); 63 } 64 // check MIME setting of DokuWiki - mime.conf/mime.local.conf 65 // Embedding will fail if the media file is to be force_download. 66 list($ext, $mtype, $force_download) = mimetype($linkId); 67 if (!$force_download) { 68 switch ($conf['userewrite']){ 69 case 0: // No URL rewriting 70 $mediapath = 'lib/exe/fetch.php?media='.$linkId; 71 break; 72 case 1: // serverside rewiteing eg. .htaccess file 73 $mediapath = '_media/'.$linkId; 74 break; 75 case 2: // DokuWiki rewiteing 76 $mediapath = 'lib/exe/fetch.php/'.$linkId; 77 break; 78 } 79 } else { 80 // try alternative url to avoid download dialog. 81 // 82 // !!! EXPERIMENTAL : WEB SITE SPECIFIC FEATURE !!! 83 // we assume "DOKU_URL/_media" directory 84 // which physically mapped or linked to 85 // your DW_DATA_PATH/media directory. 86 // WebServer solution includes htpd.conf, IIS virtual directory. 87 // Symbolic link or Junction are Filesystem solution. 88 // Example: 89 // if linux: ln -s DW_DATA_PATH/media _media 90 // if iis6(Win2003S): linkd.exe _media DW_DATA_PATH/media 91 // if iis7(Win2008S): mklink.exe /d _media DW_DATA_PATH/media 92 // 93 94 $altMediaBaseDir = $this->getConf('alternative_mediadir'); 95 if (empty($altMediaBaseDir)) $altMediaBaseDir ='/'; 96 if ($linkId[0] == ':') $linkId = substr($linkId, 1); 97 $mediapath = $altMediaBaseDir . str_replace(':','/',$linkId); 98 if ($ACT=='preview') { 99 msg($this->getPluginName().': alternative url ('.$mediapath.') will be used for '.$linkId, 2); 100 } 101 } 102 // $mediapath does not contain "http://" and hostname 103 return $mediapath; 104 } 105 106 107 108 /** 109 * handle syntax 110 */ 111 public function handle($match, $state, $pos, Doku_Handler $handler){ 112 113 $opts = array( // set default 114 'id' => '', 115 'title' => $this->getLang('gview_linktext'), 116 'class' => '', 117 'width' => '100%', 118 'height' => '300px', 119 'embedded' => true, 120 'reference' => true, 121 //'border' => false, 122 ); 123 124 list($params, $media) = explode('>', trim($match,'{}'), 2); 125 126 // handle media parameters (linkId and title) 127 list($linkId, $title) = explode('|', $media, 2); 128 129 // handle viewer parameters 130 // split phrase of parameters by white space 131 $tokens = preg_split('/\s+/', $params); 132 133 // check frist markup 134 $markup = array_shift($tokens); // first param 135 if (strpos($markup,'gview') !== false) { 136 $opts['class'] = 'gview'; 137 } elseif (strlen($markup) > 6) { 138 $opts['class'] = substr($markup,6); // strip "{{obj:" 139 } 140 141 foreach ($tokens as $token) { 142 143 // get width and height of iframe 144 $matches=array(); 145 if (preg_match('/(\d+(%|em|pt|px)?)([,xX](\d+(%|em|pt|px)?))?/',$token,$matches)){ 146 if ($matches[4]) { 147 // width and height was given 148 $opts['width'] = $matches[1]; 149 if (!$matches[2]) $opts['width'].= 'px'; //default to pixel when no unit was set 150 $opts['height'] = $matches[4]; 151 if (!$matches[5]) $opts['height'].= 'px'; //default to pixel when no unit was set 152 continue; 153 } elseif ($matches[2]) { 154 // only height was given 155 $opts['height'] = $matches[1]; 156 if (!$matches[2]) $opts['height'].= 'px'; //default to pixel when no unit was set 157 continue; 158 } 159 } 160 // get reference option, ie. whether show original document url? 161 if (preg_match('/no(reference|link)/',$token)) { 162 $opts['reference'] = false; 163 continue; 164 } 165 // get embed option 166 if (preg_match('/noembed(ded)?/',$token)) { 167 $opts['embedded'] = false; 168 continue; 169 } 170 // get border option 171 if (preg_match('/no(frame)?border/',$token)) { 172 $opts['border'] = false; 173 continue; 174 } 175 } 176 177 $opts['id'] = trim($linkId); 178 if (!empty($title)) $opts['title'] = trim($title); 179 180 return array($state, $opts); 181 } 182 183 /** 184 * Render iframe or link for Google Docs Viewer Service 185 */ 186 public function render($format, Doku_Renderer $renderer, $data) { 187 188 if ($format != 'xhtml') return false; 189 190 list($state, $opts) = $data; 191 if ( $opts['id'] =='') return false; 192 193 switch ($opts['class']) { 194 case 'gview': 195 $html = $this->_html_embed_gview($opts); 196 break; 197 default: 198 $html = $this->_html_embed($opts); 199 break; 200 } 201 $renderer->doc.=$html; 202 return true; 203 } 204 205 /** 206 * Generate html for sytax {{obj:>}} 207 */ 208 private function _html_embed($opts) { 209 210 // make reference link 211 $url = $this->_resolveMediaUrl($opts['id']); 212 $referencelink = '<a href="'.$url.'">'.urldecode($url).'</a>'; 213 214 if (empty($opts['class'])) { 215 $html = '<div class="obj_container">'.NL; 216 } else { 217 $html = '<div class="obj_container_'.$opts['class'].'">'.NL; 218 } 219 if (!$opts['embedded']) { 220 $html.= '<a href="'.$url.'">'.$opts['title'].'</a>'; 221 } else { 222 if ($opts['reference']) { 223 $html.= '<div class="obj_note">'; 224 $html.= sprintf($this->getLang('reference_msg'), $referencelink); 225 $html.= '</div>'.NL; 226 } 227 $html.= '<object data="'.urldecode($url).'"'; 228 $html.= ' style="'; 229 if ($opts['width']) { $html.= ' width: '.$opts['width'].';'; } 230 if ($opts['height']) { $html.= ' height: '.$opts['height'].';'; } 231 $html.= '">'.NL; 232 $html.= '</object>'.NL; 233 } 234 $html.= '</div>'.NL; 235 236 return $html; 237 } 238 239 /** 240 * Generate html for sytax {{obj:gview>}} or {{gview>}} 241 * 242 * @see also: https://docs.google.com/viewer# 243 */ 244 private function _html_embed_gview($opts) { 245 246 // make reference link 247 $url = DOKU_URL.$this->_resolveMediaUrl($opts['id']); 248 $referencelink = '<a href="'.$url.'">'.urldecode($url).'</a>'; 249 250 $html = '<div class="obj_container_gview">'.NL; 251 if (!$opts['embedded']) { 252 $html.= '<a href="'.$url.'">'.$opts['title'].'</a>'; 253 } else { 254 if ($opts['reference']) { 255 $html.= '<div class="obj_note">'; 256 $html.= sprintf($this->getLang('reference_msg'), $referencelink); 257 $html.= '</div>'.NL; 258 } 259 $html.= '<iframe src="'.self::URLgoogleViwer; 260 $html.= '?url='.urlencode($url); 261 $html.= '&embedded=true"'; 262 $html.= ' style="'; 263 if ($opts['width']) { $html.= ' width: '.$opts['width'].';'; } 264 if ($opts['height']) { $html.= ' height: '.$opts['height'].';'; } 265 //if ($opts['border'] == false) { $html.= ' border: none;'; } 266 $html.= ' border: none;'; 267 $html.= '"></iframe>'.NL; 268 } 269 $html.= '</div>'.NL; 270 271 return $html; 272 } 273 274} 275