1<?php
2/*
3 * XXX
4 */
5
6if(!defined('DOKU_INC')) die();
7if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
8require_once(DOKU_PLUGIN.'syntax.php');
9require_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//
15class 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