dokuwiki-source-plugin – Diff between revs 3 and 4

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 3 Rev 4
Line 20... Line 20...
20 * - php.ini setting, allow_url_fopen 20 * - php.ini setting, allow_url_fopen
21 * - php.ini setting, open_basedir 21 * - php.ini setting, open_basedir
22 * - this plugin's location, allow & deny settings. 22 * - this plugin's location, allow & deny settings.
23 * 23 *
24 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 24 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
25 * @author Wizardry and Steamworks office@grimore.org -  
26 * original: Christopher Smith <chris@jalakai.co.uk> 25 * @author Christopher Smith <chris@jalakai.co.uk>
27 */ 26 */
28 if(!defined('DOKU_INC')) die(); // no Dokuwiki, no go 27 if(!defined('DOKU_INC')) die(); // no Dokuwiki, no go
29   28
30 if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 29 if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
31 require_once(DOKU_PLUGIN.'syntax.php'); 30 require_once(DOKU_PLUGIN.'syntax.php');
32   31
33 /** 32 /**
34 * All DokuWiki plugins to extend the parser/rendering mechanism 33 * All DokuWiki plugins to extend the parser/rendering mechanism
35 * need to inherit from this class 34 * need to inherit from this class
36 */ 35 */
37 class syntax_plugin_source extends DokuWiki_Syntax_Plugin { 36 class syntax_plugin_source extends DokuWiki_Syntax_Plugin {
38   37
39 //------------------- [ Security settings ] --------------------------------------------- 38 //------------------- [ Security settings ] ---------------------------------------------
40 var $location = ''; // prepended to all file names, restricting the filespace exposed to the plugin 39 var $location = ''; // prepended to all file names, restricting the filespace exposed to the plugin
41 var $allow = array(); // if not empty, ONLY files with the extensions listed will be allowed 40 var $allow = array(); // if not empty, ONLY files with the extensions listed will be allowed
42 var $deny = array(); // if $allow array is empty, any file with an extension listed in $deny array will be denied 41 var $deny = array(); // if $allow array is empty, any file with an extension listed in $deny array will be denied
43 var $rules = array(); // more complex allow/deny rules, refer documentation 42 var $rules = array(); // more complex allow/deny rules, refer documentation
44   43
45 //------------------------[ Other settings ] --------------------------------------------- 44 //------------------------[ Other settings ] ---------------------------------------------
46 var $extensions = array( 45 var $extensions = array(
47 'htm' => 'html4strict', 46 'htm' => 'html4strict',
48 'html' => 'html4strict', 47 'html' => 'html4strict',
49 'js' => 'javascript' 48 'js' => 'javascript'
50 ); 49 );
51   50
52 /** 51 /**
53 * return some info 52 * return some info
54 */ 53 */
55 function getInfo(){ 54 function getInfo(){
56 return array( 55 return array(
Line 61... Line 60...
61 'desc' => 'Include a remote source file 60 'desc' => 'Include a remote source file
62 Syntax: <source filename #startline-endline language|title>', 61 Syntax: <source filename #startline-endline language|title>',
63 'url' => 'http://www.dokuwiki.org/plugin:source', 62 'url' => 'http://www.dokuwiki.org/plugin:source',
64 ); 63 );
65 } 64 }
66   65
67 function getType() { return 'substition'; } 66 function getType() { return 'substition'; }
68 function getPType() { return 'block'; } 67 function getPType() { return 'block'; }
69 function getSort() { return 330; } 68 function getSort() { return 330; }
70   69
71 /** 70 /**
72 * Connect pattern to lexer 71 * Connect pattern to lexer
73 */ 72 */
74 function connectTo($mode) { 73 function connectTo($mode) {
75 $this->Lexer->addSpecialPattern('<source.*?>',$mode,substr(get_class($this), 7)); 74 $this->Lexer->addSpecialPattern('<source.*?>',$mode,substr(get_class($this), 7));
76 } 75 }
77   76
78 /** 77 /**
79 * Handle the match 78 * Handle the match
80 */ 79 */
81 function handle($match, $state, $pos, Doku_Handler $handler){ 80 function handle($match, $state, $pos, Doku_Handler $handler){
82 $match = trim(substr($match,7,-1)); //strip <source from start and > from end 81 $match = trim(substr($match,7,-1)); //strip <source from start and > from end
83   82
84 // ['|"]?<filename>[\1] [#<line#>-<line#>] <lang> | <title> 83 // ['|"]?<filename>[\1] [#<line#>-<line#>] <lang> | <title>
85 list($attr, $title) = preg_split('/\|/u', $match, 2); //split out title 84 list($attr, $title) = preg_split('/\|/u', $match, 2); //split out title
86   85
87 $attr = trim($attr); 86 $attr = trim($attr);
88 $pattern = ($attr{0} == '"' || $attr{0} == "'") ? $attr{0} : '\s'; 87 $pattern = ($attr[0] == '"' || $attr[0] == "'") ? $attr[0] : '\s';
89 list($file, $prop) = preg_split("/$pattern/u", $attr, 3, PREG_SPLIT_NO_EMPTY); 88 list($file, $prop) = preg_split("/$pattern/u", $attr, 3, PREG_SPLIT_NO_EMPTY);
90   89
91 if (isset($prop) && trim($prop)) { 90 if (isset($prop) && trim($prop)) {
92 $matches = array(); 91 $matches = array();
93 if (preg_match('/\s*(?:(?:#(\d+)-(\d+))\s*)?(\w+)?/',$prop,$matches)) { 92 if (preg_match('/\s*(?:(?:#(\d+)-(\d+))\s*)?(\w+)?/',$prop,$matches)) {
94 list(,$start,$end,$lang) = $matches; 93 list(,$start,$end,$lang) = $matches;
95 if (!isset($lang)) $lang = ''; 94 if (!isset($lang)) $lang = '';
96 } 95 }
97 } else { 96 } else {
98 $start = $end = $lang = ''; 97 $start = $end = $lang = '';
99 } 98 }
100   99
101 return array(trim($file), $lang, (isset($title)?trim($title):''), $start, $end); 100 return array(trim($file), $lang, (isset($title)?trim($title):''), $start, $end);
102 } 101 }
103   102
104 /** 103 /**
105 * Create output 104 * Create output
106 */ 105 */
107 function render($format, Doku_Renderer $renderer, $data) { 106 function render($format, Doku_Renderer $renderer, $data) {
108   107
109 $this->_loadSettings(); 108 $this->_loadSettings();
110   109
111 list($file, $lang, $title, $start, $end) = $data; 110 list($file, $lang, $title, $start, $end) = $data;
112 $ext = substr(strrchr($file, '.'),1); 111 $ext = substr(strrchr($file, '.'),1);
113   112
114 $ok = false; 113 $ok = false;
115 if (count($this->allow)) { 114 if (count($this->allow)) {
116 if (in_array($ext, $this->allow)) $ok = true; 115 if (in_array($ext, $this->allow)) $ok = true;
117 } else { 116 } else {
118 if (!in_array($ext, $this->deny)) $ok = true; 117 if (!in_array($ext, $this->deny)) $ok = true;
119 } 118 }
120   119
121 // prevent filenames which attempt to move up directory tree by using ".." 120 // prevent filenames which attempt to move up directory tree by using ".."
122 if ($ok && $this->location && preg_match('/(?:^|\/)\.\.(?:\/|$)/', $file)) $ok = false; 121 if ($ok && $this->location && preg_match('/(?:^|\/)\.\.(?:\/|$)/', $file)) $ok = false;
123 if ($ok && $this->rules) $ok = $this->_checkRules($file); 122 if ($ok && $this->rules) $ok = $this->_checkRules($file);
124   123
125 if (!$lang) { $lang = isset($this->extensions[$ext]) ? $this->extensions[$ext] : $ext; } 124 if (!$lang) { $lang = isset($this->extensions[$ext]) ? $this->extensions[$ext] : $ext; }
126   125
127 switch ($format) { 126 switch ($format) {
128 case 'xhtml' : 127 case 'xhtml' :
129   128
130 if ($ok && ($source = $this->_getSource($file,$start,$end))) { 129 if ($ok && ($source = $this->_getSource($file,$start,$end))) {
131   130
132 $title = ($title) ? "<span>".hsc($title)."</span>" 131 $title = ($title) ? "<span>".hsc($title)."</span>"
133 : $this->_makeTitle($file, $start, $end); 132 : $this->_makeTitle($file, $start, $end);
134   133
135 $renderer->doc .= "<div class='source'><p class='title'>$title</p>"; 134 $renderer->doc .= "<div class='source'><p>$title</p>";
136 $renderer->code($source, $lang); 135 $renderer->code($source, $lang);
137 $renderer->doc .= "</div>"; 136 $renderer->doc .= "</div>";
138 } else { 137 } else {
139 $error = sprintf($this->getLang('error_file'),hsc($file)); 138 $error = sprintf($this->getLang('error_file'),hsc($file));
140 $renderer->doc .= '<div class="source"><p><span>'.$error.'</span></p></div>'; 139 $renderer->doc .= '<div class="source"><p><span>'.$error.'</span></p></div>';
141 } 140 }
142 break; 141 break;
143   142
144 case 'metadata' : 143 case 'metadata' :
145 if ($ok) { 144 if ($ok) {
146 $renderer->meta['relation']['haspart'][$file] = array('owner'=>$this->getPluginName()); 145 $renderer->meta['relation']['haspart'][$file] = array('owner'=>$this->getPluginName());
147 } 146 }
148 break; 147 break;
149   148
150 default : 149 default :
151 if ($ok) { 150 if ($ok) {
152 $renderer->code($this->_getSource($file,$start,$end), $lang); 151 $renderer->code($this->_getSource($file,$start,$end), $lang);
153 } 152 }
154 } 153 }
155   154
156 } 155 }
157   156
158 function _makeTitle($file,$start,$end) { 157 function _makeTitle($file,$start,$end) {
159 $lines = $start ? sprintf($this->getLang('lines'),$start,$end) : ''; 158 $lines = $start ? sprintf($this->getLang('lines'),$start,$end) : '';
160 $title = sprintf($this->getLang('title'),hsc($file),$lines); 159 $title = sprintf($this->getLang('title'),hsc($file),$lines);
161   160
162 return $title; 161 return $title;
163 } 162 }
164   163
165 function _getSource($file,$start,$end) { 164 function _getSource($file,$start,$end) {
166   165
167 $source = @file($this->location.$file); 166 $source = @file($this->location.$file);
168 if (empty($source)) return ''; 167 if (empty($source)) return '';
169   168
170 // $start is a 1 based index, need to correct to 0 based when slicing arrray 169 // $start is a 1 based index, need to correct to 0 based when slicing arrray
171 if (!empty($start)) { 170 if (!empty($start)) {
172 $lines = count($source); 171 $lines = count($source);
173 if ($start > $lines) { 172 if ($start > $lines) {
174 $source = $this->getLang('error_start'); 173 $source = $this->getLang('error_start');
Line 180... Line 179...
180 $source = join('',array_slice($source,$start-1,$end-$start)); 179 $source = join('',array_slice($source,$start-1,$end-$start));
181 } 180 }
182 } else { 181 } else {
183 $source = join('',$source); 182 $source = join('',$source);
184 } 183 }
185   184
186 return $source; 185 return $source;
187 } 186 }
188   187
189 function _checkRules($file) { 188 function _checkRules($file) {
190 $permit = true; 189 $permit = true;
191 foreach ($this->rules as $rule) { 190 foreach ($this->rules as $rule) {
192 list($allow_deny, $pattern) = $rule; 191 list($allow_deny, $pattern) = $rule;
193 if ($allow_deny == 'allow') { 192 if ($allow_deny == 'allow') {
194 if (preg_match($pattern,$file)) $permit = true; 193 if (preg_match($pattern,$file)) $permit = true;
195 } else { 194 } else {
196 if (preg_match($pattern,$file)) $permit = false; 195 if (preg_match($pattern,$file)) $permit = false;
197 } 196 }
198 } 197 }
199   198
200 return $permit; 199 return $permit;
201 } 200 }
202   201
203 function _loadSettings() { 202 function _loadSettings() {
204 static $loaded = false; 203 static $loaded = false;
205   204
206 if ($loaded) return; 205 if ($loaded) return;
207   206
208 $this->location = $this->getConf('location'); 207 $this->location = $this->getConf('location');
209   208
210 $allow = $this->getConf('allow'); 209 $allow = $this->getConf('allow');
211 $this->allow = !empty($allow) ? explode('|',$allow) : array(); 210 $this->allow = !empty($allow) ? explode('|',$allow) : array();
212   211
213 $deny = $this->getConf('deny'); 212 $deny = $this->getConf('deny');
214 $this->deny = !empty($deny) ? explode('|',$deny) : array(); 213 $this->deny = !empty($deny) ? explode('|',$deny) : array();
215   214
216 $rules = $this->getConf('rules'); 215 $rules = $this->getConf('rules');
217 if (!empty($rules)) $this->_parseRules($rules); 216 if (!empty($rules)) $this->_parseRules($rules);
218   217
219 $loaded = true; 218 $loaded = true;
220 } 219 }
221   220
222 function _parseRules($rules) { 221 function _parseRules($rules) {
223 $rules = explode("\n",$rules); 222 $rules = explode("\n",$rules);
224 foreach ($rules as $rule) { 223 foreach ($rules as $rule) {
225 $rule = trim($rule); 224 $rule = trim($rule);
226 if (!$rule || $rule{0} == ';') continue; 225 if (!$rule || $rule[0] == ';') continue;
227   226
228 $match = array(); 227 $match = array();
229 if (!preg_match('/^(allow|deny)\s+(.+)$/i',$rule,$match)) continue; 228 if (!preg_match('/^(allow|deny)\s+(.+)$/i',$rule,$match)) continue;
230   229
231 $this->rules[] = array(strtolower($match[1]),$match[2]); 230 $this->rules[] = array(strtolower($match[1]),$match[2]);
232 } 231 }
233 } 232 }
234 } 233 }
235   -  
236 //Setup VIM: ex: et ts=4 enc=utf-8 : -  
237   234
-   235 //Setup VIM: ex: et ts=4 enc=utf-8 :
-   236