1 <?php
2 /*
3  * XXX
4  */
5 
6 if(!defined('DOKU_INC')) die();
7 if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
8 require_once(DOKU_PLUGIN.'syntax.php');
9 require_once(DOKU_PLUGIN.'calendoku/helper.php');
10 
11 // start end duration contact summary url uid created last-modified
12 // sequence x-calendoku-version prodid tzname description organizer
13 // location class
14 //
15 class syntax_plugin_calendoku_showtable extends DokuWiki_Syntax_Plugin {
16 
17     function getType()  { return 'substition'; }
18     function getPType() { return 'block'; }
19     function getSort()  { return 42; }
20     function getAllowedTypes() {
21         return array('formatting', 'substition', 'paragraphs', 'baseonly');
22     }
23 
24     function connectTo($mode) {
25         $this->Lexer->addSpecialPattern(
26             '\{\{calendoku>.*?>\s*\}\}',
27             $mode,
28             'plugin_calendoku_showtable');
29     }
30 
31     function handle($match, $state, $pos, &$handler) {
32         $match = preg_replace('/^\{\{calendoku(.*)\}\}/', '\1', $match);
33 
34         /* Get the fields we want to show. */
35         $tmpfields = array();
36         if (preg_match('/(?<=>)\s*FIELDS=(.*?)(?=>)/', $match, $fieldsstr)) {
37             $this->fields = preg_split('/(?<!\\\\) /', $fieldsstr[1]);
38         } else {
39             $this->fields = array('DTSTART', 'DTEND', 'SUMMARY', 'CONTACT', 'URL');
40         }
41 
42         /* Get the formatted field descriptions. */
43         $tmpfielddescs = array();
44         if (preg_match('/(?<=>)\s*FIELDDESCS=(.*?)(?=>)/', $match, $fielddescsstr)) {
45             $this->fielddescs = preg_split('/(?<!\\\\) /', $fielddescsstr[1]);
46         } else {
47             $this->fielddescs = $tmpfields;
48         }
49 
50         /* Get the type of the calendar we want to show. */
51         if (preg_match('/(?<=>)\s*TYPE=(.*?)(?=>)/', $match, $typestr)) {
52             if (!strcmp($typestr[1], 'VTABLE'))
53                 $this->type = 'VTABLE';
54             else
55                 $this->type = 'VTABLE';
56         } else {
57             $this->type = 'VTABLE';
58         }
59 
60         /* Get the start date. */
61         if (preg_match('/(?<=>)\s*START=(.*?)(?=>)/', $match, $startstr)) {
62             if (!strcmp($startstr[1], 'CURRENT'))
63                 $startdate = guessDateTime(date('U'));
64             else
65                 $startdate = guessDateTime($startstr[1]);
66         } else {
67             $startdate = guessDateTime('0');
68         }
69 
70         /* Get the end date. */
71         if (preg_match('/(?<=>)\s*END=(.*?)(?=>)/', $match, $endstr)) {
72             if (!strcmp($endstr[1], 'CURRENT'))
73                 $enddate = guessDateTime(date('U'));
74             else {
75                 $enddate = guessDateTime($endstr[1]);
76             }
77         } else {
78             $enddate = guessDateTime('0');
79         }
80 
81         /* Get the namespaces to be searched. */
82         // XXX: Colon separation won't work for sub namespaces!
83         if (!preg_match('/(?<=>)\s*NAMESPACE=(.*?)(?=>)/', $match, $namespacestr))
84             return false;
85         $namespaces = preg_split('/(?<!\\\\) /', $namespacestr[1]);
86 
87         /* Go through all namespaces and their pages. */
88         $templates = preg_split('/\s/', $this->getConf('icaltemplates'));
89         foreach ($namespaces as $namespace) {
90             $namespace = preg_replace('/\\ /', ' ', $namespace);
91             $data = ft_pageLookup($namespace, true, false);
92             foreach($data as $pagename => $title) {
93                 if (strcmp(getNS($pagename), $namespace))
94                     continue;
95 
96                 $docontinue = false;
97                 foreach($templates as $template)
98                     if (!strcmp($template, $pagename)) {
99                         $docontinue = true;
100                         break;
101                     }
102                 if ($docontinue)
103                     continue;
104 
105                 $page = rawWiki($pagename);
106 
107                 $object = new CalenDoku_CalendarObject($this, $page);
108                 if (count($object->components) > 0) {
109                     foreach ($object->components as $component) {
110                         if ($component->invalid)
111                             continue;
112                         if ($component->isWithinTime($startdate, $enddate)) {
113                             if (isset($components[$component->dtstartint]))
114                                 array_push($components[$component->dtstartint], array($component, $pagename));
115                             else
116                                 $components[$component->dtstartint] = array(array($component, $pagename));
117                         }
118                     }
119                 }
120             }
121         }
122 
123 
124         /* Insert pages sorted. */
125         ksort($components, SORT_NUMERIC);
126         $this->startCalendar($pos, $handler);
127         foreach ($components as $mcomponent) {
128             foreach ($mcomponent as $component) {
129                 $this->addEntryCalendar($component[0], $component[1], $pos, $handler);
130             }
131         }
132         $this->endCalendar($pos, $handler);
133     }
134 
135     function startCalendar($pos, &$handler) {
136         if (!strcmp($this->type, 'VTABLE')) {
137             $handler->_addCall('table_open', array(), $pos);
138             $handler->_addCall('tablerow_open', array(), $pos);
139             foreach ($this->fielddescs as $fielddesc) {
140                 $handler->_addCall('tableheader_open', array(), $pos);
141                 reHandleText($fielddesc, $pos, $handler);
142                 $handler->_addCall('tableheader_close', array(), $pos);
143             }
144             $handler->_addCall('tablerow_close', array(), $pos);
145         }
146     }
147 
148     function endCalendar($pos, &$handler) {
149         if (!strcmp($this->type, 'VTABLE'))
150             $handler->_addCall('table_close', array(), $pos);
151     }
152 
153     function addEntryCalendar($component, $pagename, $pos, &$handler) {
154         $handler->_addCall('tablerow_open', array(), $pos);
155         foreach ($this->fields as $field) {
156             preg_match_all('/(@@.*?@@)/', $field, $matches);
157             foreach ($matches[1] as $match) {
158                 $sfield = preg_replace('/@@(.*)@@/', '\1', $match);
159                 if (!strcmp($sfield, 'DOKUWIKILINK'))
160                     $field = preg_replace('/'.$match.'/', $pagename, $field);
161                 else if (!strcmp($sfield, 'DOKUWIKIICAL'))
162                     $field = preg_replace('/'.$match.'/', $pagename.'?do=ical', $field);
163                 else if (isset($component->renderfields[$sfield]))
164                     $field = preg_replace('/'.$match.'/', $component->renderfields[$sfield], $field);
165                 else
166                     $field = preg_replace('/'.$match.'/', '', $field);
167             }
168             $handler->_addCall('tablecell_open', array(), $pos);
169             reHandleText($field, $pos, $handler);
170             $handler->_addCall('tablecell_close', array(), $pos);
171         }
172         $handler->_addCall('tablerow_close', array(), $pos);
173     }
174 
175     function render($mode, &$renderer, $data) {
176         return true;
177     }
178 }
179 //Setup VIM: ex: et ts=4 enc=utf-8 :
180