1<?php 2// must be run within DokuWiki 3if(!defined('DOKU_INC')) die(); 4 5if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 6require_once DOKU_PLUGIN.'syntax.php'; 7 8/** 9 * Plugin maps drive letters to a unc path. 10 */ 11class syntax_plugin_uncmap extends DokuWiki_Syntax_Plugin { 12 13 /** 14 * stores an array with the mappings. 15 * 16 * format is 17 * letter => path 18 */ 19 var $pathes = array(); 20 21 /** 22 * the path to the mounted fileserver. 23 * 24 * this is used for linkchecking. if the path is null the linkcheck is disabled. 25 */ 26 var $fileserver = array(0 => null); 27 28 /** 29 * load the mapping array. 30 */ 31 function syntax_plugin_uncmap() { 32 33 $lines = @file( dirname(__FILE__) . '/conf/mapping.php' ); 34 if ( $lines ) { 35 $lines_fs = array(); 36 $lines_pathes = array(); 37 foreach ($lines as $line) { 38 if (preg_match('/[a-z]/',strtolower($line[0])) == 1) { 39 $letter = $line[0]; 40 $line = substr($line,1); 41 $line = trim($line); 42 if (empty($line)) continue; 43 $delim = strpos($line,' '); 44 if ($delim === false){ 45 $lines_pathes[] = implode(' ',array($letter,$line)); 46 $lines_fs[] = implode(' ',array($letter,'default')); 47 } else { 48 $path = substr($line,0,$delim); 49 $fs = substr($line,$delim); 50 $fs = trim($fs); 51 $lines_pathes[] = implode(' ',array($letter,$path)); 52 $lines_fs[] = implode(' ',array($letter,$fs)); 53 } 54 } 55 } 56 57 $this->pathes = linesToHash($lines_pathes); 58 $this->fileserver[0] = $this->getConf('fileserver'); 59 $this->fileserver = $this->fileserver + linesToHash($lines_fs); 60 foreach ($this->fileserver as $letter => $fs) { 61 if($fs !== null && file_exists($fs)) { 62 63 $fs = str_replace('\\', '/', $fs); 64 $fs = rtrim($fs, '/'); 65 if(substr($fs, -1) == '/') { 66 $fs = substr($fs, 0, -1); 67 } 68 $this->fileserver[$letter] = $fs; 69 } elseif ($this->fileserver[0] === null || !file_exists($this->fileserver[0])){ 70 $this->fileserver[$letter] = null; 71 } else { 72 $this->fileserver[$letter] = $this->fileserver[0]; 73 } 74 } 75 } 76 } 77 78 /** 79 * syntax type is formating 80 */ 81 function getType() { return 'formatting'; } 82 83 /** 84 * a very important plugin ;-) 85 */ 86 function getSort() { return 282; } 87 88 /** 89 * connect to the renderer. 90 */ 91 function connectTo($mode) { 92 $letters = implode('',array_keys($this->pathes)); 93 if($letters !== '') { 94 $this->Lexer->addSpecialPattern('\[\[[' . strtolower($letters) . strtoupper($letters) . ']{1}\:[\\\/]{1}.+?\]\]', $mode, 'plugin_uncmap'); 95 } 96 } 97 98 /** 99 * review the given url. 100 */ 101 function handle($match, $state, $pos, Doku_Handler $handler) { 102 103 // trim [[ and ]] 104 $match = substr($match,2,-2); 105 106 // remove surrounding whitespaces 107 $match = trim($match); 108 109 // get the drive letter in lower case 110 $letter = strtolower($match[0]); 111 $return = array(); 112 $return['letter'] = $letter; 113 // if there is a mapping for the drive letter we have work to do 114 if ($this->pathes[$letter]) { 115 $titlepos = strpos($match,'|'); 116 if ($titlepos !== false){ 117 $title = substr($match,$titlepos+1); 118 $match = substr($match,0,$titlepos); 119 $return['title'] = $title; 120 } else { 121 $return['title'] = null; 122 } 123 // get the mapping path 124 $path = $this->pathes[$letter]; 125 $match = substr($match, 1); 126 127 $match = str_replace('/','\\',$match); 128 129 // ensure it is a real path 130 if (substr($match,0,2) == ':\\') { 131 132 // build windows share link 133 $new = $path; 134 if (substr($path,-1) != '\\') $new .= '\\'; 135 $new .= substr($match,2); 136 } 137 $return['url'] = $new; 138 } 139 140 return $return; 141 } 142 143 /** 144 * displays the link. 145 */ 146 function render($mode, Doku_Renderer $renderer, $data) { 147 if($mode == 'xhtml'){ 148 149 // check if there is a link and give it to the renderer 150 if (!empty($data['url'])) { 151 $renderer->windowssharelink($data['url'], $data['title']); 152 153 // check if the linked file exists on the fileserver and set the class accordingly 154 $data['exists'] = $this->checkLink($data); 155 if ($data['exists'] == 1) { 156 $this->replaceLinkClass($renderer,'wikilink1'); 157 } elseif ($data['exists'] == -1) { 158 $this->replaceLinkClass($renderer,'wikilink2'); 159 } 160 } 161 } 162 return false; 163 } 164 165 /** 166 * checks if the link exists on the server. 167 */ 168 function checkLink($data) { 169 if (!$this->fileserver[$data['letter']]) { 170 return null; 171 } 172 173 $data['url'] = str_replace('\\','/',$data['url']); 174 $path = preg_replace('/^\/\/[^\/]+/i',$this->fileserver[$data['letter']],$data['url']); 175 176 return file_exists($path)?1:-1; 177 } 178 179 /** 180 * @param Doku_Renderer $renderer: 181 * @param $newClass: replace the class of the windowssharelink with this value 182 */ 183 function replaceLinkClass(Doku_Renderer $renderer, $newClass){ 184 $ourdoc = & $renderer->doc; 185 186 //detach the link from doc 187 $linkoffset = strrpos($ourdoc,'<a '); 188 $link = substr($ourdoc, $linkoffset); 189 $ourdoc = substr($ourdoc, 0, $linkoffset); 190 $link = preg_replace('/class=\"(windows|media)\"/','class="' . $newClass . '"',$link); 191 192 $ourdoc .= $link; 193 } 194 195} 196