register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'handle_pagewrite'); $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_deliverical'); } function handle_deliverical(&$event, $param) { if (!is_string($event->data) || strcmp($event->data, 'ical')) return; $INFO = pageinfo(); $namespaces = preg_split('/\s/', $this->getconf('icalnamespaces')); $dohandle = false; foreach ($namespaces as $namespace) if (!strcmp($INFO['namespace'], $namespace)) { $dohandle = true; break; } if (!$dohandle) return; if (auth_quickaclcheck($INFO['id']) < AUTH_READ) return; header('Content-type: text/calendar'); header('Content-disposition: attachment; filename="'.$INFO['id'].'.ics"'); die(file_get_contents($INFO['filepath'])); } function handle_pagewrite(&$event, $param) { /* data[3] is false for the current page, set to revision otherwise. */ if ($event->data[3]) return; if (!strcmp($this->getConf('icalnamespaces'), '')) return; /* Namespace. false if root ns. */ if (!isset($event->data[1])) return; $templates = preg_split('/\s/', $this->getConf('icaltemplates')); foreach ($templates as $template) if (!strcmp($template, $event->data[2])) return; $dohandle = false; $namespaces = preg_split('/\s/', $this->getConf('icalnamespaces')); foreach ($namespaces as $namespace) if (!strcmp($event->data[1], $namespace)) { $dohandle = true; break; } if (!$dohandle) return; $event->data[0][1] = $this->reparseTemplateWrite($event->data[0][1]); } function reparseTemplateWrite($text) { // XXX: BEGIN:VCALENDAR $textlines = preg_split('/\n/', $text); $newtext = ''; $inparse = false; $now = new DateTime('now'); foreach ($textlines as $line) { /* Get DTSTAMP or LAST-MODIFIED. They have to be changed. */ if (!$inparse && (preg_match('/^(DTSTAMP:)/', $line, $match) || preg_match('/^(LAST-MODIFIED:)/', $line, $match))) { $newtext .= $match[1].$now->format('Ymd').'T'.$now->format('His')."\n"; continue; } /* Get datetime lines, i.e. YYYY-MM-DD hh:mm. */ if (!$inparse && preg_match('/^([[:alnum:]-]*?):@@([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9-]{1,2}):([0-9-]{1,2})@@$/', $line, $match)) { if (!strcmp($match[5], '-') || !strcmp($match[6], '-')) { $newtext .= $match[1].':'.$match[2].$match[3].$match[4]."\n"; } else { if (count($match[5]) == 1) $match[5] = '0'.$match[5]; if (count($match[6]) == 1) $match[6] = '0'.$match[6]; $newtext .= $match[1].':'.$match[2].$match[3].$match[4].'T'.$match[5].$match[6].'00'."\n"; } continue; } /* Single-line field. */ if (!$inparse && preg_match('/^([[:alnum:]-]*?):@@(.*)@@$/', $line, $match)) { $newtext .= $match[1].':'.$match[2]."\n"; continue; } /* Start of some added field. */ if (!$inparse && preg_match('/^([[:alnum:]-]*?):@@(.*)$/', $line, $match)) { $newtext .= $match[1].':'.$match[2]."\n"; $inparse = true; continue; } /* End of a field. */ if ($inparse && preg_match('/^(.*)@@$/', $line, $match)) { $newtext .= ' '.$match[1]."\n"; $inparse = false; continue; } /* In the middle of some added field. */ if ($inparse) { $newtext .= ' '.$line."\n"; continue; } /* Nothing found. */ $newtext .= $line."\n"; } /* Remove trailing newline. */ $newtext = substr($newtext, 0, -1); return $newtext; } } // vim:ts=4:sw=4:et:enc=utf-8: