1 | <?php
|
---|
2 | /**
|
---|
3 | * DokuWiki Actions
|
---|
4 | *
|
---|
5 | * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
---|
6 | * @author Andreas Gohr <[email protected]>
|
---|
7 | */
|
---|
8 |
|
---|
9 | if(!defined('DOKU_INC')) die('meh.');
|
---|
10 |
|
---|
11 | /**
|
---|
12 | * Call the needed action handlers
|
---|
13 | *
|
---|
14 | * @author Andreas Gohr <[email protected]>
|
---|
15 | * @triggers ACTION_ACT_PREPROCESS
|
---|
16 | * @triggers ACTION_HEADERS_SEND
|
---|
17 | */
|
---|
18 | function act_dispatch(){
|
---|
19 | global $ACT;
|
---|
20 | global $ID;
|
---|
21 | global $INFO;
|
---|
22 | global $QUERY;
|
---|
23 | global $lang;
|
---|
24 | global $conf;
|
---|
25 |
|
---|
26 | $preact = $ACT;
|
---|
27 |
|
---|
28 | // give plugins an opportunity to process the action
|
---|
29 | $evt = new Doku_Event('ACTION_ACT_PREPROCESS',$ACT);
|
---|
30 | if ($evt->advise_before()) {
|
---|
31 |
|
---|
32 | //sanitize $ACT
|
---|
33 | $ACT = act_clean($ACT);
|
---|
34 |
|
---|
35 | //check if searchword was given - else just show
|
---|
36 | $s = cleanID($QUERY);
|
---|
37 | if($ACT == 'search' && empty($s)){
|
---|
38 | $ACT = 'show';
|
---|
39 | }
|
---|
40 |
|
---|
41 | //login stuff
|
---|
42 | if(in_array($ACT,array('login','logout'))){
|
---|
43 | $ACT = act_auth($ACT);
|
---|
44 | }
|
---|
45 |
|
---|
46 | //check if user is asking to (un)subscribe a page
|
---|
47 | if($ACT == 'subscribe') {
|
---|
48 | try {
|
---|
49 | $ACT = act_subscription($ACT);
|
---|
50 | } catch (Exception $e) {
|
---|
51 | msg($e->getMessage(), -1);
|
---|
52 | }
|
---|
53 | }
|
---|
54 |
|
---|
55 | //display some infos
|
---|
56 | if($ACT == 'check'){
|
---|
57 | check();
|
---|
58 | $ACT = 'show';
|
---|
59 | }
|
---|
60 |
|
---|
61 | //check permissions
|
---|
62 | $ACT = act_permcheck($ACT);
|
---|
63 |
|
---|
64 | //sitemap
|
---|
65 | if ($ACT == 'sitemap'){
|
---|
66 | $ACT = act_sitemap($ACT);
|
---|
67 | }
|
---|
68 |
|
---|
69 | //register
|
---|
70 | if($ACT == 'register' && $_POST['save'] && register()){
|
---|
71 | $ACT = 'login';
|
---|
72 | }
|
---|
73 |
|
---|
74 | if ($ACT == 'resendpwd' && act_resendpwd()) {
|
---|
75 | $ACT = 'login';
|
---|
76 | }
|
---|
77 |
|
---|
78 | //update user profile
|
---|
79 | if ($ACT == 'profile') {
|
---|
80 | if(!$_SERVER['REMOTE_USER']) {
|
---|
81 | $ACT = 'login';
|
---|
82 | } else {
|
---|
83 | if(updateprofile()) {
|
---|
84 | msg($lang['profchanged'],1);
|
---|
85 | $ACT = 'show';
|
---|
86 | }
|
---|
87 | }
|
---|
88 | }
|
---|
89 |
|
---|
90 | //revert
|
---|
91 | if($ACT == 'revert'){
|
---|
92 | if(checkSecurityToken()){
|
---|
93 | $ACT = act_revert($ACT);
|
---|
94 | }else{
|
---|
95 | $ACT = 'show';
|
---|
96 | }
|
---|
97 | }
|
---|
98 |
|
---|
99 | //save
|
---|
100 | if($ACT == 'save'){
|
---|
101 | if(checkSecurityToken()){
|
---|
102 | $ACT = act_save($ACT);
|
---|
103 | }else{
|
---|
104 | $ACT = 'show';
|
---|
105 | }
|
---|
106 | }
|
---|
107 |
|
---|
108 | //cancel conflicting edit
|
---|
109 | if($ACT == 'cancel')
|
---|
110 | $ACT = 'show';
|
---|
111 |
|
---|
112 | //draft deletion
|
---|
113 | if($ACT == 'draftdel')
|
---|
114 | $ACT = act_draftdel($ACT);
|
---|
115 |
|
---|
116 | //draft saving on preview
|
---|
117 | if($ACT == 'preview')
|
---|
118 | $ACT = act_draftsave($ACT);
|
---|
119 |
|
---|
120 | //edit
|
---|
121 | if(in_array($ACT, array('edit', 'preview', 'recover'))) {
|
---|
122 | $ACT = act_edit($ACT);
|
---|
123 | }else{
|
---|
124 | unlock($ID); //try to unlock
|
---|
125 | }
|
---|
126 |
|
---|
127 | //handle export
|
---|
128 | if(substr($ACT,0,7) == 'export_')
|
---|
129 | $ACT = act_export($ACT);
|
---|
130 |
|
---|
131 | //handle admin tasks
|
---|
132 | if($ACT == 'admin'){
|
---|
133 | // retrieve admin plugin name from $_REQUEST['page']
|
---|
134 | if (!empty($_REQUEST['page'])) {
|
---|
135 | $pluginlist = plugin_list('admin');
|
---|
136 | if (in_array($_REQUEST['page'], $pluginlist)) {
|
---|
137 | // attempt to load the plugin
|
---|
138 | if ($plugin =& plugin_load('admin',$_REQUEST['page']) !== null){
|
---|
139 | if($plugin->forAdminOnly() && !$INFO['isadmin']){
|
---|
140 | // a manager tried to load a plugin that's for admins only
|
---|
141 | unset($_REQUEST['page']);
|
---|
142 | msg('For admins only',-1);
|
---|
143 | }else{
|
---|
144 | $plugin->handle();
|
---|
145 | }
|
---|
146 | }
|
---|
147 | }
|
---|
148 | }
|
---|
149 | }
|
---|
150 |
|
---|
151 | // check permissions again - the action may have changed
|
---|
152 | $ACT = act_permcheck($ACT);
|
---|
153 | } // end event ACTION_ACT_PREPROCESS default action
|
---|
154 | $evt->advise_after();
|
---|
155 | // Make sure plugs can handle 'denied'
|
---|
156 | if($conf['send404'] && $ACT == 'denied') {
|
---|
157 | header('HTTP/1.0 403 Forbidden');
|
---|
158 | }
|
---|
159 | unset($evt);
|
---|
160 |
|
---|
161 | // when action 'show', the intial not 'show' and POST, do a redirect
|
---|
162 | if($ACT == 'show' && $preact != 'show' && strtolower($_SERVER['REQUEST_METHOD']) == 'post'){
|
---|
163 | act_redirect($ID,$preact);
|
---|
164 | }
|
---|
165 |
|
---|
166 | global $INFO;
|
---|
167 | global $conf;
|
---|
168 | global $license;
|
---|
169 |
|
---|
170 | //call template FIXME: all needed vars available?
|
---|
171 | $headers[] = 'Content-Type: text/html; charset=utf-8';
|
---|
172 | trigger_event('ACTION_HEADERS_SEND',$headers,'act_sendheaders');
|
---|
173 |
|
---|
174 | include(template('main.php'));
|
---|
175 | // output for the commands is now handled in inc/templates.php
|
---|
176 | // in function tpl_content()
|
---|
177 | }
|
---|
178 |
|
---|
179 | function act_sendheaders($headers) {
|
---|
180 | foreach ($headers as $hdr) header($hdr);
|
---|
181 | }
|
---|
182 |
|
---|
183 | /**
|
---|
184 | * Sanitize the action command
|
---|
185 | *
|
---|
186 | * Add all allowed commands here.
|
---|
187 | *
|
---|
188 | * @author Andreas Gohr <[email protected]>
|
---|
189 | */
|
---|
190 | function act_clean($act){
|
---|
191 | global $lang;
|
---|
192 | global $conf;
|
---|
193 | global $INFO;
|
---|
194 |
|
---|
195 | // check if the action was given as array key
|
---|
196 | if(is_array($act)){
|
---|
197 | list($act) = array_keys($act);
|
---|
198 | }
|
---|
199 |
|
---|
200 | //remove all bad chars
|
---|
201 | $act = strtolower($act);
|
---|
202 | $act = preg_replace('/[^1-9a-z_]+/','',$act);
|
---|
203 |
|
---|
204 | if($act == 'export_html') $act = 'export_xhtml';
|
---|
205 | if($act == 'export_htmlbody') $act = 'export_xhtmlbody';
|
---|
206 |
|
---|
207 | if($act === '') $act = 'show';
|
---|
208 |
|
---|
209 | // check if action is disabled
|
---|
210 | if(!actionOK($act)){
|
---|
211 | msg('Command disabled: '.htmlspecialchars($act),-1);
|
---|
212 | return 'show';
|
---|
213 | }
|
---|
214 |
|
---|
215 | //disable all acl related commands if ACL is disabled
|
---|
216 | if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin',
|
---|
217 | 'subscribe','unsubscribe','profile','revert',
|
---|
218 | 'resendpwd','subscribens','unsubscribens',))){
|
---|
219 | msg('Command unavailable: '.htmlspecialchars($act),-1);
|
---|
220 | return 'show';
|
---|
221 | }
|
---|
222 |
|
---|
223 | //is there really a draft?
|
---|
224 | if($act == 'draft' && !file_exists($INFO['draft'])) return 'edit';
|
---|
225 |
|
---|
226 | if(!in_array($act,array('login','logout','register','save','cancel','edit','draft',
|
---|
227 | 'preview','search','show','check','index','revisions',
|
---|
228 | 'diff','recent','backlink','admin','subscribe','revert',
|
---|
229 | 'unsubscribe','profile','resendpwd','recover',
|
---|
230 | 'draftdel','subscribens','unsubscribens','sitemap')) && substr($act,0,7) != 'export_' ) {
|
---|
231 | msg('Command unknown: '.htmlspecialchars($act),-1);
|
---|
232 | return 'show';
|
---|
233 | }
|
---|
234 | return $act;
|
---|
235 | }
|
---|
236 |
|
---|
237 | /**
|
---|
238 | * Run permissionchecks
|
---|
239 | *
|
---|
240 | * @author Andreas Gohr <[email protected]>
|
---|
241 | */
|
---|
242 | function act_permcheck($act){
|
---|
243 | global $INFO;
|
---|
244 | global $conf;
|
---|
245 |
|
---|
246 | if(in_array($act,array('save','preview','edit','recover'))){
|
---|
247 | if($INFO['exists']){
|
---|
248 | if($act == 'edit'){
|
---|
249 | //the edit function will check again and do a source show
|
---|
250 | //when no AUTH_EDIT available
|
---|
251 | $permneed = AUTH_READ;
|
---|
252 | }else{
|
---|
253 | $permneed = AUTH_EDIT;
|
---|
254 | }
|
---|
255 | }else{
|
---|
256 | $permneed = AUTH_CREATE;
|
---|
257 | }
|
---|
258 | }elseif(in_array($act,array('login','search','recent','profile','index', 'sitemap'))){
|
---|
259 | $permneed = AUTH_NONE;
|
---|
260 | }elseif($act == 'revert'){
|
---|
261 | $permneed = AUTH_ADMIN;
|
---|
262 | if($INFO['ismanager']) $permneed = AUTH_EDIT;
|
---|
263 | }elseif($act == 'register'){
|
---|
264 | $permneed = AUTH_NONE;
|
---|
265 | }elseif($act == 'resendpwd'){
|
---|
266 | $permneed = AUTH_NONE;
|
---|
267 | }elseif($act == 'admin'){
|
---|
268 | if($INFO['ismanager']){
|
---|
269 | // if the manager has the needed permissions for a certain admin
|
---|
270 | // action is checked later
|
---|
271 | $permneed = AUTH_READ;
|
---|
272 | }else{
|
---|
273 | $permneed = AUTH_ADMIN;
|
---|
274 | }
|
---|
275 | }else{
|
---|
276 | $permneed = AUTH_READ;
|
---|
277 | }
|
---|
278 | if($INFO['perm'] >= $permneed) return $act;
|
---|
279 |
|
---|
280 | return 'denied';
|
---|
281 | }
|
---|
282 |
|
---|
283 | /**
|
---|
284 | * Handle 'draftdel'
|
---|
285 | *
|
---|
286 | * Deletes the draft for the current page and user
|
---|
287 | */
|
---|
288 | function act_draftdel($act){
|
---|
289 | global $INFO;
|
---|
290 | @unlink($INFO['draft']);
|
---|
291 | $INFO['draft'] = null;
|
---|
292 | return 'show';
|
---|
293 | }
|
---|
294 |
|
---|
295 | /**
|
---|
296 | * Saves a draft on preview
|
---|
297 | *
|
---|
298 | * @todo this currently duplicates code from ajax.php :-/
|
---|
299 | */
|
---|
300 | function act_draftsave($act){
|
---|
301 | global $INFO;
|
---|
302 | global $ID;
|
---|
303 | global $conf;
|
---|
304 | if($conf['usedraft'] && $_POST['wikitext']){
|
---|
305 | $draft = array('id' => $ID,
|
---|
306 | 'prefix' => substr($_POST['prefix'], 0, -1),
|
---|
307 | 'text' => $_POST['wikitext'],
|
---|
308 | 'suffix' => $_POST['suffix'],
|
---|
309 | 'date' => (int) $_POST['date'],
|
---|
310 | 'client' => $INFO['client'],
|
---|
311 | );
|
---|
312 | $cname = getCacheName($draft['client'].$ID,'.draft');
|
---|
313 | if(io_saveFile($cname,serialize($draft))){
|
---|
314 | $INFO['draft'] = $cname;
|
---|
315 | }
|
---|
316 | }
|
---|
317 | return $act;
|
---|
318 | }
|
---|
319 |
|
---|
320 | /**
|
---|
321 | * Handle 'save'
|
---|
322 | *
|
---|
323 | * Checks for spam and conflicts and saves the page.
|
---|
324 | * Does a redirect to show the page afterwards or
|
---|
325 | * returns a new action.
|
---|
326 | *
|
---|
327 | * @author Andreas Gohr <[email protected]>
|
---|
328 | */
|
---|
329 | function act_save($act){
|
---|
330 | global $ID;
|
---|
331 | global $DATE;
|
---|
332 | global $PRE;
|
---|
333 | global $TEXT;
|
---|
334 | global $SUF;
|
---|
335 | global $SUM;
|
---|
336 | global $lang;
|
---|
337 | global $INFO;
|
---|
338 |
|
---|
339 | //spam check
|
---|
340 | if(checkwordblock()) {
|
---|
341 | msg($lang['wordblock'], -1);
|
---|
342 | return 'edit';
|
---|
343 | }
|
---|
344 | //conflict check
|
---|
345 | if($DATE != 0 && $INFO['meta']['date']['modified'] > $DATE )
|
---|
346 | return 'conflict';
|
---|
347 |
|
---|
348 | //save it
|
---|
349 | saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$_REQUEST['minor']); //use pretty mode for con
|
---|
350 | //unlock it
|
---|
351 | unlock($ID);
|
---|
352 |
|
---|
353 | //delete draft
|
---|
354 | act_draftdel($act);
|
---|
355 | session_write_close();
|
---|
356 |
|
---|
357 | // when done, show page
|
---|
358 | return 'show';
|
---|
359 | }
|
---|
360 |
|
---|
361 | /**
|
---|
362 | * Revert to a certain revision
|
---|
363 | *
|
---|
364 | * @author Andreas Gohr <[email protected]>
|
---|
365 | */
|
---|
366 | function act_revert($act){
|
---|
367 | global $ID;
|
---|
368 | global $REV;
|
---|
369 | global $lang;
|
---|
370 | // FIXME $INFO['writable'] currently refers to the attic version
|
---|
371 | // global $INFO;
|
---|
372 | // if (!$INFO['writable']) {
|
---|
373 | // return 'show';
|
---|
374 | // }
|
---|
375 |
|
---|
376 | // when no revision is given, delete current one
|
---|
377 | // FIXME this feature is not exposed in the GUI currently
|
---|
378 | $text = '';
|
---|
379 | $sum = $lang['deleted'];
|
---|
380 | if($REV){
|
---|
381 | $text = rawWiki($ID,$REV);
|
---|
382 | if(!$text) return 'show'; //something went wrong
|
---|
383 | $sum = $lang['restored'];
|
---|
384 | }
|
---|
385 |
|
---|
386 | // spam check
|
---|
387 |
|
---|
388 | if (checkwordblock($text)) {
|
---|
389 | msg($lang['wordblock'], -1);
|
---|
390 | return 'edit';
|
---|
391 | }
|
---|
392 |
|
---|
393 | saveWikiText($ID,$text,$sum,false);
|
---|
394 | msg($sum,1);
|
---|
395 |
|
---|
396 | //delete any draft
|
---|
397 | act_draftdel($act);
|
---|
398 | session_write_close();
|
---|
399 |
|
---|
400 | // when done, show current page
|
---|
401 | $_SERVER['REQUEST_METHOD'] = 'post'; //should force a redirect
|
---|
402 | $REV = '';
|
---|
403 | return 'show';
|
---|
404 | }
|
---|
405 |
|
---|
406 | /**
|
---|
407 | * Do a redirect after receiving post data
|
---|
408 | *
|
---|
409 | * Tries to add the section id as hash mark after section editing
|
---|
410 | */
|
---|
411 | function act_redirect($id,$preact){
|
---|
412 | global $PRE;
|
---|
413 | global $TEXT;
|
---|
414 |
|
---|
415 | $opts = array(
|
---|
416 | 'id' => $id,
|
---|
417 | 'preact' => $preact
|
---|
418 | );
|
---|
419 | //get section name when coming from section edit
|
---|
420 | if($PRE && preg_match('/^\s*==+([^=\n]+)/',$TEXT,$match)){
|
---|
421 | $check = false; //Byref
|
---|
422 | $opts['fragment'] = sectionID($match[0], $check);
|
---|
423 | }
|
---|
424 |
|
---|
425 | trigger_event('ACTION_SHOW_REDIRECT',$opts,'act_redirect_execute');
|
---|
426 | }
|
---|
427 |
|
---|
428 | function act_redirect_execute($opts){
|
---|
429 | $go = wl($opts['id'],'',true);
|
---|
430 | if(isset($opts['fragment'])) $go .= '#'.$opts['fragment'];
|
---|
431 |
|
---|
432 | //show it
|
---|
433 | send_redirect($go);
|
---|
434 | }
|
---|
435 |
|
---|
436 | /**
|
---|
437 | * Handle 'login', 'logout'
|
---|
438 | *
|
---|
439 | * @author Andreas Gohr <[email protected]>
|
---|
440 | */
|
---|
441 | function act_auth($act){
|
---|
442 | global $ID;
|
---|
443 | global $INFO;
|
---|
444 |
|
---|
445 | //already logged in?
|
---|
446 | if(isset($_SERVER['REMOTE_USER']) && $act=='login'){
|
---|
447 | return 'show';
|
---|
448 | }
|
---|
449 |
|
---|
450 | //handle logout
|
---|
451 | if($act=='logout'){
|
---|
452 | $lockedby = checklock($ID); //page still locked?
|
---|
453 | if($lockedby == $_SERVER['REMOTE_USER'])
|
---|
454 | unlock($ID); //try to unlock
|
---|
455 |
|
---|
456 | // do the logout stuff
|
---|
457 | auth_logoff();
|
---|
458 |
|
---|
459 | // rebuild info array
|
---|
460 | $INFO = pageinfo();
|
---|
461 |
|
---|
462 | act_redirect($ID,'login');
|
---|
463 | }
|
---|
464 |
|
---|
465 | return $act;
|
---|
466 | }
|
---|
467 |
|
---|
468 | /**
|
---|
469 | * Handle 'edit', 'preview', 'recover'
|
---|
470 | *
|
---|
471 | * @author Andreas Gohr <[email protected]>
|
---|
472 | */
|
---|
473 | function act_edit($act){
|
---|
474 | global $ID;
|
---|
475 | global $INFO;
|
---|
476 |
|
---|
477 | global $TEXT;
|
---|
478 | global $RANGE;
|
---|
479 | global $PRE;
|
---|
480 | global $SUF;
|
---|
481 | global $REV;
|
---|
482 | global $SUM;
|
---|
483 | global $lang;
|
---|
484 | global $DATE;
|
---|
485 |
|
---|
486 | if (!isset($TEXT)) {
|
---|
487 | if ($INFO['exists']) {
|
---|
488 | if ($RANGE) {
|
---|
489 | list($PRE,$TEXT,$SUF) = rawWikiSlices($RANGE,$ID,$REV);
|
---|
490 | } else {
|
---|
491 | $TEXT = rawWiki($ID,$REV);
|
---|
492 | }
|
---|
493 | } else {
|
---|
494 | $TEXT = pageTemplate($ID);
|
---|
495 | }
|
---|
496 | }
|
---|
497 |
|
---|
498 | //set summary default
|
---|
499 | if(!$SUM){
|
---|
500 | if($REV){
|
---|
501 | $SUM = $lang['restored'];
|
---|
502 | }elseif(!$INFO['exists']){
|
---|
503 | $SUM = $lang['created'];
|
---|
504 | }
|
---|
505 | }
|
---|
506 |
|
---|
507 | // Use the date of the newest revision, not of the revision we edit
|
---|
508 | // This is used for conflict detection
|
---|
509 | if(!$DATE) $DATE = $INFO['meta']['date']['modified'];
|
---|
510 |
|
---|
511 | //check if locked by anyone - if not lock for my self
|
---|
512 | //do not lock when the user can't edit anyway
|
---|
513 | if ($INFO['writable']) {
|
---|
514 | $lockedby = checklock($ID);
|
---|
515 | if($lockedby) return 'locked';
|
---|
516 |
|
---|
517 | lock($ID);
|
---|
518 | }
|
---|
519 |
|
---|
520 | return $act;
|
---|
521 | }
|
---|
522 |
|
---|
523 | /**
|
---|
524 | * Export a wiki page for various formats
|
---|
525 | *
|
---|
526 | * Triggers ACTION_EXPORT_POSTPROCESS
|
---|
527 | *
|
---|
528 | * Event data:
|
---|
529 | * data['id'] -- page id
|
---|
530 | * data['mode'] -- requested export mode
|
---|
531 | * data['headers'] -- export headers
|
---|
532 | * data['output'] -- export output
|
---|
533 | *
|
---|
534 | * @author Andreas Gohr <[email protected]>
|
---|
535 | * @author Michael Klier <[email protected]>
|
---|
536 | */
|
---|
537 | function act_export($act){
|
---|
538 | global $ID;
|
---|
539 | global $REV;
|
---|
540 | global $conf;
|
---|
541 | global $lang;
|
---|
542 |
|
---|
543 | $pre = '';
|
---|
544 | $post = '';
|
---|
545 | $output = '';
|
---|
546 | $headers = array();
|
---|
547 |
|
---|
548 | // search engines: never cache exported docs! (Google only currently)
|
---|
549 | $headers['X-Robots-Tag'] = 'noindex';
|
---|
550 |
|
---|
551 | $mode = substr($act,7);
|
---|
552 | switch($mode) {
|
---|
553 | case 'raw':
|
---|
554 | $headers['Content-Type'] = 'text/plain; charset=utf-8';
|
---|
555 | $headers['Content-Disposition'] = 'attachment; filename='.noNS($ID).'.txt';
|
---|
556 | $output = rawWiki($ID,$REV);
|
---|
557 | break;
|
---|
558 | case 'xhtml':
|
---|
559 | $pre .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' . DOKU_LF;
|
---|
560 | $pre .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . DOKU_LF;
|
---|
561 | $pre .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"' . DOKU_LF;
|
---|
562 | $pre .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF;
|
---|
563 | $pre .= '<head>' . DOKU_LF;
|
---|
564 | $pre .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . DOKU_LF;
|
---|
565 | $pre .= ' <title>'.$ID.'</title>' . DOKU_LF;
|
---|
566 |
|
---|
567 | // get metaheaders
|
---|
568 | ob_start();
|
---|
569 | tpl_metaheaders();
|
---|
570 | $pre .= ob_get_clean();
|
---|
571 |
|
---|
572 | $pre .= '</head>' . DOKU_LF;
|
---|
573 | $pre .= '<body>' . DOKU_LF;
|
---|
574 | $pre .= '<div class="dokuwiki export">' . DOKU_LF;
|
---|
575 |
|
---|
576 | // get toc
|
---|
577 | $pre .= tpl_toc(true);
|
---|
578 |
|
---|
579 | $headers['Content-Type'] = 'text/html; charset=utf-8';
|
---|
580 | $output = p_wiki_xhtml($ID,$REV,false);
|
---|
581 |
|
---|
582 | $post .= '</div>' . DOKU_LF;
|
---|
583 | $post .= '</body>' . DOKU_LF;
|
---|
584 | $post .= '</html>' . DOKU_LF;
|
---|
585 | break;
|
---|
586 | case 'xhtmlbody':
|
---|
587 | $headers['Content-Type'] = 'text/html; charset=utf-8';
|
---|
588 | $output = p_wiki_xhtml($ID,$REV,false);
|
---|
589 | break;
|
---|
590 | default:
|
---|
591 | $output = p_cached_output(wikiFN($ID,$REV), $mode);
|
---|
592 | $headers = p_get_metadata($ID,"format $mode");
|
---|
593 | break;
|
---|
594 | }
|
---|
595 |
|
---|
596 | // prepare event data
|
---|
597 | $data = array();
|
---|
598 | $data['id'] = $ID;
|
---|
599 | $data['mode'] = $mode;
|
---|
600 | $data['headers'] = $headers;
|
---|
601 | $data['output'] =& $output;
|
---|
602 |
|
---|
603 | trigger_event('ACTION_EXPORT_POSTPROCESS', $data);
|
---|
604 |
|
---|
605 | if(!empty($data['output'])){
|
---|
606 | if(is_array($data['headers'])) foreach($data['headers'] as $key => $val){
|
---|
607 | header("$key: $val");
|
---|
608 | }
|
---|
609 | print $pre.$data['output'].$post;
|
---|
610 | exit;
|
---|
611 | }
|
---|
612 | return 'show';
|
---|
613 | }
|
---|
614 |
|
---|
615 | /**
|
---|
616 | * Handle sitemap delivery
|
---|
617 | *
|
---|
618 | * @author Michael Hamann <[email protected]>
|
---|
619 | */
|
---|
620 | function act_sitemap($act) {
|
---|
621 | global $conf;
|
---|
622 |
|
---|
623 | if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) {
|
---|
624 | header("HTTP/1.0 404 Not Found");
|
---|
625 | print "Sitemap generation is disabled.";
|
---|
626 | exit;
|
---|
627 | }
|
---|
628 |
|
---|
629 | $sitemap = Sitemapper::getFilePath();
|
---|
630 | if(strrchr($sitemap, '.') === '.gz'){
|
---|
631 | $mime = 'application/x-gzip';
|
---|
632 | }else{
|
---|
633 | $mime = 'application/xml; charset=utf-8';
|
---|
634 | }
|
---|
635 |
|
---|
636 | // Check if sitemap file exists, otherwise create it
|
---|
637 | if (!is_readable($sitemap)) {
|
---|
638 | Sitemapper::generate();
|
---|
639 | }
|
---|
640 |
|
---|
641 | if (is_readable($sitemap)) {
|
---|
642 | // Send headers
|
---|
643 | header('Content-Type: '.$mime);
|
---|
644 | header('Content-Disposition: attachment; filename='.basename($sitemap));
|
---|
645 |
|
---|
646 | http_conditionalRequest(filemtime($sitemap));
|
---|
647 |
|
---|
648 | // Send file
|
---|
649 | //use x-sendfile header to pass the delivery to compatible webservers
|
---|
650 | if (http_sendfile($sitemap)) exit;
|
---|
651 |
|
---|
652 | readfile($sitemap);
|
---|
653 | exit;
|
---|
654 | }
|
---|
655 |
|
---|
656 | header("HTTP/1.0 500 Internal Server Error");
|
---|
657 | print "Could not read the sitemap file - bad permissions?";
|
---|
658 | exit;
|
---|
659 | }
|
---|
660 |
|
---|
661 | /**
|
---|
662 | * Handle page 'subscribe'
|
---|
663 | *
|
---|
664 | * Throws exception on error.
|
---|
665 | *
|
---|
666 | * @author Adrian Lang <[email protected]>
|
---|
667 | */
|
---|
668 | function act_subscription($act){
|
---|
669 | global $lang;
|
---|
670 | global $INFO;
|
---|
671 | global $ID;
|
---|
672 |
|
---|
673 | // subcriptions work for logged in users only
|
---|
674 | if(!$_SERVER['REMOTE_USER']) return 'show';
|
---|
675 |
|
---|
676 | // get and preprocess data.
|
---|
677 | $params = array();
|
---|
678 | foreach(array('target', 'style', 'action') as $param) {
|
---|
679 | if (isset($_REQUEST["sub_$param"])) {
|
---|
680 | $params[$param] = $_REQUEST["sub_$param"];
|
---|
681 | }
|
---|
682 | }
|
---|
683 |
|
---|
684 | // any action given? if not just return and show the subscription page
|
---|
685 | if(!$params['action'] || !checkSecurityToken()) return $act;
|
---|
686 |
|
---|
687 | // Handle POST data, may throw exception.
|
---|
688 | trigger_event('ACTION_HANDLE_SUBSCRIBE', $params, 'subscription_handle_post');
|
---|
689 |
|
---|
690 | $target = $params['target'];
|
---|
691 | $style = $params['style'];
|
---|
692 | $data = $params['data'];
|
---|
693 | $action = $params['action'];
|
---|
694 |
|
---|
695 | // Perform action.
|
---|
696 | if (!subscription_set($_SERVER['REMOTE_USER'], $target, $style, $data)) {
|
---|
697 | throw new Exception(sprintf($lang["subscr_{$action}_error"],
|
---|
698 | hsc($INFO['userinfo']['name']),
|
---|
699 | prettyprint_id($target)));
|
---|
700 | }
|
---|
701 | msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
|
---|
702 | prettyprint_id($target)), 1);
|
---|
703 | act_redirect($ID, $act);
|
---|
704 |
|
---|
705 | // Assure that we have valid data if act_redirect somehow fails.
|
---|
706 | $INFO['subscribed'] = get_info_subscribed();
|
---|
707 | return 'show';
|
---|
708 | }
|
---|
709 |
|
---|
710 | /**
|
---|
711 | * Validate POST data
|
---|
712 | *
|
---|
713 | * Validates POST data for a subscribe or unsubscribe request. This is the
|
---|
714 | * default action for the event ACTION_HANDLE_SUBSCRIBE.
|
---|
715 | *
|
---|
716 | * @author Adrian Lang <[email protected]>
|
---|
717 | */
|
---|
718 | function subscription_handle_post(&$params) {
|
---|
719 | global $INFO;
|
---|
720 | global $lang;
|
---|
721 |
|
---|
722 | // Get and validate parameters.
|
---|
723 | if (!isset($params['target'])) {
|
---|
724 | throw new Exception('no subscription target given');
|
---|
725 | }
|
---|
726 | $target = $params['target'];
|
---|
727 | $valid_styles = array('every', 'digest');
|
---|
728 | if (substr($target, -1, 1) === ':') {
|
---|
729 | // Allow âlistâ subscribe style since the target is a namespace.
|
---|
730 | $valid_styles[] = 'list';
|
---|
731 | }
|
---|
732 | $style = valid_input_set('style', $valid_styles, $params,
|
---|
733 | 'invalid subscription style given');
|
---|
734 | $action = valid_input_set('action', array('subscribe', 'unsubscribe'),
|
---|
735 | $params, 'invalid subscription action given');
|
---|
736 |
|
---|
737 | // Check other conditions.
|
---|
738 | if ($action === 'subscribe') {
|
---|
739 | if ($INFO['userinfo']['mail'] === '') {
|
---|
740 | throw new Exception($lang['subscr_subscribe_noaddress']);
|
---|
741 | }
|
---|
742 | } elseif ($action === 'unsubscribe') {
|
---|
743 | $is = false;
|
---|
744 | foreach($INFO['subscribed'] as $subscr) {
|
---|
745 | if ($subscr['target'] === $target) {
|
---|
746 | $is = true;
|
---|
747 | }
|
---|
748 | }
|
---|
749 | if ($is === false) {
|
---|
750 | throw new Exception(sprintf($lang['subscr_not_subscribed'],
|
---|
751 | $_SERVER['REMOTE_USER'],
|
---|
752 | prettyprint_id($target)));
|
---|
753 | }
|
---|
754 | // subscription_set deletes a subscription if style = null.
|
---|
755 | $style = null;
|
---|
756 | }
|
---|
757 |
|
---|
758 | $data = in_array($style, array('list', 'digest')) ? time() : null;
|
---|
759 | $params = compact('target', 'style', 'data', 'action');
|
---|
760 | }
|
---|
761 |
|
---|
762 | //Setup VIM: ex: et ts=2 :
|
---|