1<?php 2if(!defined('DOKU_INC')) die(); 3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 4 5require_once(DOKU_PLUGIN.'action.php'); 6 7class action_plugin_calendoku extends DokuWiki_Action_Plugin { 8 function register(&$controller) { 9 $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'handle_pagewrite'); 10 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_deliverical'); 11 } 12 13 function handle_deliverical(&$event, $param) { 14 if (!is_string($event->data) || strcmp($event->data, 'ical')) 15 return; 16 $INFO = pageinfo(); 17 18 $namespaces = preg_split('/\s/', $this->getconf('icalnamespaces')); 19 $dohandle = false; 20 foreach ($namespaces as $namespace) 21 if (!strcmp($INFO['namespace'], $namespace)) { 22 $dohandle = true; 23 break; 24 } 25 if (!$dohandle) 26 return; 27 28 if (auth_quickaclcheck($INFO['id']) < AUTH_READ) 29 return; 30 31 header('Content-type: text/calendar'); 32 header('Content-disposition: attachment; filename="'.$INFO['id'].'.ics"'); 33 die(file_get_contents($INFO['filepath'])); 34 } 35 36 function handle_pagewrite(&$event, $param) { 37 /* data[3] is false for the current page, set to revision otherwise. */ 38 if ($event->data[3]) 39 return; 40 41 if (!strcmp($this->getConf('icalnamespaces'), '')) 42 return; 43 44 /* Namespace. false if root ns. */ 45 if (!isset($event->data[1])) 46 return; 47 48 $templates = preg_split('/\s/', $this->getConf('icaltemplates')); 49 foreach ($templates as $template) 50 if (!strcmp($template, $event->data[2])) 51 return; 52 53 $dohandle = false; 54 $namespaces = preg_split('/\s/', $this->getConf('icalnamespaces')); 55 foreach ($namespaces as $namespace) 56 if (!strcmp($event->data[1], $namespace)) { 57 $dohandle = true; 58 break; 59 } 60 if (!$dohandle) 61 return; 62 63 $event->data[0][1] = $this->reparseTemplateWrite($event->data[0][1]); 64 } 65 66 function reparseTemplateWrite($text) { 67 // XXX: BEGIN:VCALENDAR 68 $textlines = preg_split('/\n/', $text); 69 $newtext = ''; 70 71 $inparse = false; 72 $now = new DateTime('now'); 73 foreach ($textlines as $line) { 74 /* Get DTSTAMP or LAST-MODIFIED. They have to be changed. */ 75 if (!$inparse && (preg_match('/^(DTSTAMP:)/', $line, $match) 76 || preg_match('/^(LAST-MODIFIED:)/', $line, $match))) { 77 $newtext .= $match[1].$now->format('Ymd').'T'.$now->format('His')."\n"; 78 continue; 79 } 80 81 /* Get datetime lines, i.e. YYYY-MM-DD hh:mm. */ 82 if (!$inparse && preg_match('/^([[:alnum:]-]*?):@@([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9-]{1,2}):([0-9-]{1,2})@@$/', $line, $match)) { 83 if (!strcmp($match[5], '-') || !strcmp($match[6], '-')) { 84 $newtext .= $match[1].':'.$match[2].$match[3].$match[4]."\n"; 85 } else { 86 if (count($match[5]) == 1) 87 $match[5] = '0'.$match[5]; 88 if (count($match[6]) == 1) 89 $match[6] = '0'.$match[6]; 90 $newtext .= $match[1].':'.$match[2].$match[3].$match[4].'T'.$match[5].$match[6].'00'."\n"; 91 } 92 continue; 93 } 94 95 /* Single-line field. */ 96 if (!$inparse && preg_match('/^([[:alnum:]-]*?):@@(.*)@@$/', $line, $match)) { 97 $newtext .= $match[1].':'.$match[2]."\n"; 98 continue; 99 } 100 101 /* Start of some added field. */ 102 if (!$inparse && preg_match('/^([[:alnum:]-]*?):@@(.*)$/', $line, $match)) { 103 $newtext .= $match[1].':'.$match[2]."\n"; 104 $inparse = true; 105 continue; 106 } 107 108 /* End of a field. */ 109 if ($inparse && preg_match('/^(.*)@@$/', $line, $match)) { 110 $newtext .= ' '.$match[1]."\n"; 111 $inparse = false; 112 continue; 113 } 114 115 /* In the middle of some added field. */ 116 if ($inparse) { 117 $newtext .= ' '.$line."\n"; 118 continue; 119 } 120 121 /* Nothing found. */ 122 $newtext .= $line."\n"; 123 } 124 125 /* Remove trailing newline. */ 126 $newtext = substr($newtext, 0, -1); 127 128 return $newtext; 129 } 130} 131 132// vim:ts=4:sw=4:et:enc=utf-8: 133